Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you eval code in the context of a caller in Ruby?

Tags:

Essentially I'm wondering if the following can be done in Ruby.

So for example:

def bar(symbol)    # magic code goes here, it outputs "a = 100"  end  def foo   a = 100    bar(:a)  end 
like image 329
Sam Saffron Avatar asked Aug 31 '09 10:08

Sam Saffron


People also ask

How does eval work in Ruby?

Ruby's eval takes in a string as the argument, which means that it is possible for one to accept user input or read code off of a file and get it evaluated from within your program - essentially re-programming the way your program behaves.

What does context mean in Ruby?

A Context is something that can hold modules, classes, methods, attributes, aliases, requires, and includes. Classes, modules, and files are all Contexts.


2 Answers

You have to pass foo's context to bar:

def foo   a = 100   bar(:a, binding) end def bar(sym, b)   puts "#{sym} is #{eval(sym.to_s, b)}" end 
like image 75
glenn jackman Avatar answered Nov 08 '22 23:11

glenn jackman


There is no built-in way to get a callers binding in Ruby in 1.8.X or 1.9.X.

You can use https://github.com/banister/binding_of_caller to work around.

In MRI 2.0 you can use RubyVM::DebugInspector, see: https://github.com/banister/binding_of_caller/blob/master/lib/binding_of_caller/mri2.rb

Working sample in MRI 2.0:

require 'debug_inspector'  def bar(symbol)   RubyVM::DebugInspector.open do |inspector|     val = eval(symbol.to_s, inspector.frame_binding(2))     puts "#{symbol}: #{val}"   end end  def foo   a = 100   bar(:a) end  foo # a: 100 
like image 27
Sam Saffron Avatar answered Nov 09 '22 00:11

Sam Saffron