Resident eval - code: Ruby. Survival guide
ruby metaprogrammingThere are many many ways to evaluate any ruby code at runtime. Let’s look at them.
eval
The most basic and well-known in other dynamic languages method. Receives a string and run it as a Ruby code.
Optionally you can pass a context which eval
operates on with binding
.
Binding allows you to capture current execution context. For example, it’s used by closures.
instance_eval
Allows you to operate on object with self
set to this object. It also can accept block instead of string to evaluate it. Somewhat similar to eval
with binding
.
instance_exec
Similar to instance_eval
, but also allows you to pass an argument to a block.
class_eval
Similar to instance_eval
, but operates on object itself. Available only on Module
(Class
).
class_exec
Like instance_exec
but for class_eval
. Allows you to pass an argument to a block.
module_eval
Same as class_eval
.
module_exec
Same as class_exec
.
Conclusion
eval
is the most basic and well-known method. You can evaluate any Ruby code with it. But if you’re using rubocop
it will yell at eval
as a security issue. True, if you run eval
against user-provided string it can be exploited like SQL-injection.
Other methods are a little bit safer since they accept block, not a string (don’t use strings with {instance,class,module}_eval).
obj.instance_{eval,exec}
operate on singleton class of an obj
.
obj.{class,module}_{exec,eval}
operate on obj
itself and available only on Module
(Class
).
{instance,module,class}_exec
allows you to pass an argument to eval’d block while {instance,module,class}_eval
don’t.
{instance,module,class}_eval
can also accept string (just like regular eval
).
Links
- Eval, module_eval, and instance_eval
- Kernel#eval at ruby-doc.org
- BasicObject#instance_eval
- BasicObject#instance_exec
- Module#module_eval
- Module#module_exec
- RubyMonk: Class eval
- Module#class_eval
- Module#class_exec
- Stanford CS 142: Understanding class_eval and instance_eval
- Understanding class_eval, module_eval and instance_eval
- StackOverflow: What is the difference between class_eval, class_exec, module_eval and module_exec?
- RubyMonk: Eval