As a dynamic script language, Ruby provides a few different options to evaluate a string or a block of code: eval, class_eval, module_eval, and instance_eval. What is the difference between them? This article describes it well. The main different is the context: instance_eval evaluates in the context of a certain instance, module_eval (and class_eval) in the context of a class, and eval in the current context or the context of the given binding.
Object.instance_eval evaluates a string (or the given block) within the context of a certain class instance and allows thus the direct access to class properties without attr or attr_accessor. It allows you to define new methods for a instance
class Klass def initialize @secret = 99 end end k = Klass.new k.instance_eval("@secret") # => "99" k.instance_eval("@secret=42") # => "42" k.instance_eval("def hi() \"Hello there\" end") k.hi() # => "Hello there"
Kernel.eval evaluates a string in the current context or the context of the given binding. It is the method used by IRB to process your input. It allows you to define new variables and methods for the current context.
def secret(number) return binding end number = "42" eval "number" #=> "42" eval "number", secret("99") #=> "99" eval "def hi() \"Hello there\" end" hi() # => "Hello there"
As the name says, Module.module_eval evaluates the string or block in the context of a module or class (Synonym: class_eval). module_eval allows you to define new instance method for a class.
String.module_eval do def secret "42" end end "string".secret #=> "42"