I'm learning ruby metaprogramming at the moment and while I was playing around and testing stuff, I stumbled upon something I can't seem to find the answer to. Let's say we have the following code:
class Foo
end
Foo.instance_eval do
define_method("bar") do
1
end
end
I would expect this to add a class method called bar
to Foo
but instead when I call the method it says it's undefined. What baffles me even more is that the same code works when I use def
instead of define_method
. Both ways seem to work when I try to define an instance method with class_eval
as well. So what's really going on here?
Thanks in advance.
Let's make it simple.
define_method
is a method. Or I should say a private class method of Object class. You invoke it by giving it an argument as instance method name you are going to define, and a block which contains the code of the method. apidock has very clear definition. You may want to read documentation.
def
is a keyword. You use this to define methods just as you do all the time. Not really related to meta-programming.
If you are trying define class method, use class_eval, and give it a string. As its name indicates, instance_eval
defines stuffs on instance level. In your code, if you do Foo.instance_methods
, you will find the bar
method. So if you do Foo.new.bar
it returns 1
, as TK-421 answered you. But since define_method
defines instance_method, as indicated by documentation, regardless if you use class_eval or instance_eval, you will get instance method.
Here's the documentations you can read and they will answer all you question.
class_eval: http://apidock.com/ruby/v1_9_3_392/Module/class_eval
define_method: http://apidock.com/ruby/Module/define_method
instance_eval: http://apidock.com/ruby/Object/instance_eval
And don't forget this all mighty: http://www.google.com :D