Metaprogramming in ruby is great because I constantly use it to emulate prototype based programming and quickly write prototype solutions to some problems to test their viabilit
No difference for define_method
. But there is a difference when you use def
.
o = Object.new
# class_eval example
class << o; self; end.class_eval { def test1; :test1; end }
o.test1 #=> test1
# instance_eval example
class << o; self; end.instance_eval { def test2; :test2; end }
o.test2 #=> NoMethodError
Why the difference in behaviour between def
and define_method
?
define_method
is a method call and so operates on the self
in the eval context. The self
in both instance_eval
and class_eval
is the same - it is the receiver (the eigenclass of o).
However def
behaves differently, it does not operate on the self
but instead on the default define. In the case of class_eval
the default definee
is the same as self
but for instance_eval
it is instead the metaclass of self
.
How do we access the test2
method defined above? test2 must be an instance method defined on the metaclass of the eigenclass of o.
It is a class method on the eigenclass of o:
class << o; test2; end #=> :test2