The Ruby Binding class is a pretty interesting idea. It allows you to execute code within the execution context of an instance of an object.
“Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of self, and possibly an iterator block that can be accessed in this context are all retained. Binding objects can be created using Kernel#binding, and are made available to the callback of
Kernel#set_trace_func.” - Class: Binding (Ruby 1.9.3) Documentation
Using Kernel#eval you can run code within the context of a binding. Each class that has Kernel mixed in has a binding.
Let’s try an example:
class Person
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def get_binding
binding
end
def to_s
"#{@first_name} #{@last_name}"
end
end
mo = Person.new("mo", "khan")
p mo # "mo khan"
eval("@first_name='magic'", mo.get_binding)
p mo # "magic khan"
When you give eval a binding it executes the block of ruby code within
the context of the binding. In this case a private instance variable
named @first_name was re-assigned a value of ‘magic’.
This can be quite useful when rendering an ERB template and passing it a binding. An example of this is in the RAILS code base. When you assign an instance variable in a controller this is how the variable is made available to the erb view template.