Reputation: 152
I want to change a singleton_class method of a certain class for it to do the same as it was doing before but also do something else, For example apart from what it was doing, to do:
Ok, so i know how to redefine a normal method of a class to actually do the same as it was doing before but also do something else, it would be like this:
class Class
def addHelloToMethod(methodName)
unboundMethod = instance_method(methodName)
define_method(methodName) do |*args, &block|
result =unboundMethod.bind(self).(*args, &block)
puts "hello"
result
end
end
end
What i need is to actually add this "hello" to a singleton_class method so i tried this:
class Class
def addHelloToSingletonClassMethod(methodName)
unboundMethod = singleton_class.instance_method(methodName)
singleton_class.define_method(methodName) do |*args, &block|
result =unboundMethod.bind(self).(*args, &block)
puts "hello"
result
end
end
end
What am i doing wrong here?
Upvotes: 1
Views: 102
Reputation: 10054
One way of doing this is to prepend an anonymous module that overrides the desired method, prints hello, and calls super
to invoke the actual implementation.
I'm not sure why you're adding this method to Class
. Is your goal to call the addHelloToSingletonClassMethod
on an instance of a class such as this?
irb> s = "foo"
irb> s.addHelloToSingletonClassMethod(:upcase)
irb> s.upcase
hello
=> "FOO"
If so, define the following on Object
:
class Object
def addHelloToSingletonClassMethod(methodName)
mod = Module.new
mod.define_method(methodName) do |*args, &blk|
puts "hello"
super(*args, &blk)
end
singleton_class.prepend(mod)
end
end
Or in more typical Ruby naming convention:
class Object
def add_hello_to_method(name)
mod = Module.new
mod.define_method(name) do |*args, &blk|
puts "hello"
super(*args, &blk)
end
singleton_class.prepend(mod)
end
end
If your goal on the other hand is to be able to call it on a class as follows
irb> String.addHelloToSingletonClassMethod(:upcase)
irb> "foo".upcase
hello
=> "FOO"
then you want to define it on Class
:
class Class
def add_hello_to_method(name)
mod = Module.new
mod.define_method(name) do |*args, &blk|
puts "hello"
super(*args, &blk)
end
prepend(mod)
end
end
Upvotes: 3
Reputation: 1189
Change change addHelloToSingletonClassMethod
to self.addHelloToSingletonClassMethod
. It should be a class method.
Upvotes: 0