I'm trying to dynamically call instance methods. I found send, call, eval to do that. There are examples of dynamically calling class methods, but I haven't figured out how to make it work for instance methods.
e.g.
module MyModule
def Foo
puts "hello"
end
end
the instance method names can be listed by:
MyModule.instance_methods
#=> [:Foo]
But I can't figure out how to call the method:
MyModule.send("Foo")
#=> NoMethodError: undefined method `Foo' for MyModule:Module
MyModule.method("Foo").call
#=> NameError: undefined method `Foo' for class `Module'
eval 'MyModule.Foo'
#=> NoMethodError: undefined method `Foo' for MyModule:Module
How can I call the instance methods, like Foo, by the method name?
Disclaimer: Bad practice and it makes little to no sense:
MyModule.instance_method(:Foo) # #<UnboundMethod: MyModule#Foo>
.bind(Object) # #<Method: MyModule#Foo>
.call #=> hello
You can't call an unbound method, thus you have to first bind it to some object.
References:
Module#instance_method
UnboundMethod#bind
Method#call
It would be much easier if you make the method singleton method:
module MyModule
def self.Foo
puts "hello"
end
end
MyModule.Foo
#=> "hello"
Another option is to use module_function (read up on the method's visibility for the including object when using this option):
module MyModule
def Foo
puts "hello"
end
module_function :Foo
end
MyModule.Foo
#=> "hello"
And yet another one is using extend self:
module MyModule
def Foo
puts "hello"
end
extend self
end
MyModule.Foo
#=> "hello"
P.S. It is not conventional to use capital letters in method names. It is very rare case in Ruby where it can be used and your case is 100% not the one :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With