Skip to content

Instantly share code, notes, and snippets.

@jourdein
Created November 26, 2020 20:38
Show Gist options
  • Save jourdein/1f912c79cb046934d70371ad6e2408a0 to your computer and use it in GitHub Desktop.
Save jourdein/1f912c79cb046934d70371ad6e2408a0 to your computer and use it in GitHub Desktop.
Overwrite Class/Instance methods (keyword: class_eval by itself, instance_eval & class_eval included)
# This structure will not overwrite bar class method.
# calling super will call the included module's bar.
# http://tech.tulentsev.com/2012/02/ruby-how-to-override-class-method-with-a-module/
module FooModule
def self.included base
base.extend ClassMethods
end
module ClassMethods
def bar
puts "module"
end
end
end
class Klass
include FooModule
def self.bar
puts 'class'
end
end
Klass.bar #=> class
puts [1, 2, 3].to_s #=> [1, 2, 3]
class Array
def to_s
"an array: #{join ', '}"
end
end
puts [1, 2, 3].to_s #=> an array: 1, 2, 3
# Similar code using `class_eval`
puts [1, 2, 3].to_s #=> [1, 2, 3]
Array.class_eval do
def to_s
"an array: #{join ', '}"
end
end
puts [1, 2, 3].to_s #=> an array: 1, 2, 3
class Klass
def self.say
puts 'class'
end
end
module FooModule
def self.included base
base.instance_eval do
def say
puts "module"
end
end
end
end
Klass.send(:include, FooModule)
Klass.say #=> module
class Klass
def say
puts 'class'
end
end
module FooModule
def self.included(base)
base.class_eval do
def say
puts "module"
end
end
end
end
Klass.send(:include, FooModule)
Klass.new.say #=> module
# https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073
# will look into the `module` methods first before looking into the class
module ServiceDebugger
def run(args)
puts "Service run start: #{args.inspect}"
result = super
puts "Service run finished: #{result}"
end
end
class Service
prepend ServiceDebugger
# perform some real work
def run(args)
args.each do |arg|
sleep 1
end
{result: "ok"}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment