Reputation: 1290
According to ruby-doc.org, kernel#eval
takes a binding object as the second argument as follows:
Const = 7
p eval("Const", binding) # => 7
The method eval
can be used with an object returned by a method get_binding
that accepts one parameter:
def get_binding(param)
return binding
end
n = get_binding(7)
p eval("param", n) # => 7
In the first piece of code, we get the value of Const
, and in the second piece of code, we get the value of param
. If we use eval
and binding
to retrieve values that we already know, what are these methods useful for?
Upvotes: 4
Views: 1512
Reputation: 18762
For sake of discussion, lets say you are working on a template engine - which will process a given text and replace the Ruby code in it with the its value. We can use eval
for that.
Being a general purpose engine, the template text should allow usage of Ruby variables, whose value will be defined in the caller's binding. In such cases, by passing binding to the eval
, we can allow user's binding to be used for variable evaluation.
A rudimentary, not elegant, approach is demonstrated below:
template = "Hello @first_name@ @last_name@"
def process(template, b)
vars = template.scan(/@(\w+)@/).flatten
vars.each {|v| template = template.gsub("@#{v}@", eval("#{v}", b)) }
return template
end
first_name = "Wand"
last_name = "Maker"
str = process(template, binding)
p str
#=> "Hello Wand Maker"
first_name = "Rubeus"
last_name = "Hagrid"
p process(template, binding)
#=> "Hello Rubeus Hagrid"
A somewhat similar approach has been used in ERB, Ruby's in-built template engine. You can take a look at source code
Upvotes: 3