I am reading the Module
documentation but can't seem to understand their differences and which should be used where.
How is the eval
different than exec
?
class_eval(array_second) adds the method second to any instance of Array by passing a String that will be evaluated in the context of the class Array . The call to String. class_eval with a block will evaluate the content of the block in the context of the class String .
class_eval is a method of the Module class, meaning that the receiver will be a module or a class. The block you pass to class_eval is evaluated in the context of that class. Defining a method with the standard def keyword within a class defines an instance method, and that's exactly what happens here.
I'm going to answer a bit more than your question by including instance_{eval|exec}
in your question.
All variations of {instance|module|class}_{eval|exec}
change the current context, i.e. the value for self
:
class Array p self # prints "Array" 43.instance_eval{ p self } # prints "43" end
Now for the differences. The eval
versions accepts a string or a block, while the exec
versions only accept a block but allow you to pass parameters to it:
def example(&block) 42.instance_exec("Hello", &block) end example{|mess| p mess, self } # Prints "Hello" then "42"
The eval
version does not allow to pass parameters. It provides self
as the first parameter, although I can't think of a use for this.
Finally, module_{eval|exec}
is the same as the corresponding class_{eval|exec}
, but they are slightly different from instance_{eval|exec}
as they change what is the current opened class (i.e. what will be affected by def
) in different ways:
String.instance_eval{ def foo; end } Integer.class_eval { def bar; end } String.method_defined?(:foo) # => false String.singleton_methods.include?(:foo) # => true Integer.method_defined?(:bar) # => true
So obj.instance_{eval|exec}
opens the singleton class of obj
, while mod.{class|module}_{eval|exec}
opens mod
itself.
Of course, instance_{eval|exec}
are available on any Ruby object (including modules), while {class|module}_*
are only available on Module
(and thus Classes
)
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