Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: difference between def and define_method

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.

like image 277
Robert Avatar asked Jun 23 '26 19:06

Robert


1 Answers

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

like image 89
Edmund Lee Avatar answered Jun 30 '26 12:06

Edmund Lee



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!