Problem
You've written a method that evaluates a string as Ruby code. But whenever anyone calls the method, the objects referenced by your string go out of scope. Your string can't be evaluated within a method.
For instance, here's a method that takes a variable name and tries to print out the value of the variable.
def broken_print_variable(var_name) eval %{puts "The value of #{var_name} is " + #{var_name}.to_s} end
The eval code only works when it's run in the same context as the variable definition. It doesn't work as a method, because your local variables go out of scope when you call a method.
tin_snips = 5 broken_print_variable('tin_snips') # NameError: undefined local variable or method 'tin_snips' for main:Object var_name = 'tin_snips' eval %{puts "The value of #{var_name} is " + #{var_name}.to_s} # The value of tin_snips is 5
Solution
The eval method can execute a string of Ruby code as though you had written in some other part of your application. This magic is made possible by Binding objects. You can get a Binding at any time by calling Kernel#binding, and pass it in to eval to recreate your original environment where it wouldn't otherwise be available. Here's a version of the above method that takes a Binding:
def print_variable(var_name, binding) eval %{puts "The value of #{var_name} is " + #{var_name}.to_s}, binding end vice_grips = 10 print_variable('vice_grips', binding) # The value of vice_grips is 10
Discussion
A Binding object is a bookmark of the Ruby interpreter's state. It tracks the values of any local variables you have defined, whether you are inside a class or method definition, and so on.
Once you have a Binding object, you can pass it into eval to run code in the same context as when you created the Binding. All the local variables you had back then will be available. If you called Kernel#binding within a class definition, you'll also be able to define new methods of that class, and set class and instance variables.
Since a Binding object contains references to all the objects that were in scope when it was created, those objects can't be garbage-collected until both they and the Binding object have gone out of scope.
See Also
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration