Asarluhi
Asarluhi

Reputation: 1290

eval and binding: what are they useful for?

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

Answers (1)

Wand Maker
Wand Maker

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

Related Questions