Reputation: 866
My question is based on an answer to the topic “redefining a single ruby method on a single instance with a lambda”.
How can I redefine a method and from within the new method call the original definition? Other instances of some_object
's class should not become affected.
def some_object.some_method
# call original `some_object.some_method` here
do_something_else
end
Upvotes: 3
Views: 2306
Reputation: 110665
class Klass
def greeting
puts "hiya"
end
def add_personal_greeting(str)
define_singleton_method(:greeting) do
super
puts str
end
end
end
Bob gets a handle and tries the standard greeting.
bob = Klass.new
#=> #<Klass:0x007fa66b084ad0>
bob.greeting
# hiya
He finds that too impersonal so he decides to add "I'm Bob" after the greeting. He does that by defining a method greeting
on his singleton class that calls Klass
's instance method greeting
and then adds another line to the greeting.
bob.add_personal_greeting("I'm Bob")
He tries it.
bob.greeting
# hiya
# I'm Bob
Much better. Note
bob.singleton_class.superclass
#=> Klass
Meanwhile, Lucy tries the standard greeting.
lucy = Klass.new
#=> #<Klass:0x007fa66a9ed050>
lucy.greeting
# hiya
She's not wild about it, but it will do.
Bob decides to change his greeting.
bob.add_personal_greeting("I'm Robert")
and tries it.
bob.greeting
# hiya
# I'm Robert
Upvotes: 1
Reputation: 8888
If some_object.some_method
is not a singleton method, then you can just call super
in your redefined method.
def some_object.some_method
super
do_something_else
end
If some_object.some_method
is a singleton method, then
You can define that method in a module
module SomeModule
def some_method
super
do_something_else
end
end
And then prepend it to the singleton class of the object
some_object.singleton_class.prepend(SomeModule)
You have to make an alias then redefine, since there is no Module#prepend
.
class << some_object # open the singleton class of some_object
alias some_method_original some_method
def some_method
some_method_original
do_something_else
end
end
Upvotes: 6