Is this possible in Ruby

D

Damjan Rems

Just an idea which may come in handy. Can this be done and how in Ruby.

def calc(what)
some_eval(what)
end

a=10
b=12
calc('a+b') # expression as parameters
=> 12 # would return

a='aa'
b='bb'
calc('a+b')
=> 'aabb'

This is of course strictly hypothetical. I would like the expression to
be evaluated inside the method using variables which are local to the
calling part.


by
TheR
 
S

Sean O'Halpin

Just an idea which may come in handy. Can this be done and how in Ruby.

def calc(what)
some_eval(what)
end

a=10
b=12
calc('a+b') # expression as parameters
=> 12 # would return

a='aa'
b='bb'
calc('a+b')
=> 'aabb'

This is of course strictly hypothetical. I would like the expression to
be evaluated inside the method using variables which are local to the
calling part.


by
TheR

ruby 1.9 comes with Binding#eval. In 1.8.6 you can do this:

class Binding
def eval(str)
Kernel.eval(str, self)
end
end

a = 10
b = 12
binding.eval('a + b') # => 22

def another(c, d)
binding.eval('c + d')
end
another(20, 22) # => 42

Regards,
Sean
 
L

List.rb

ruby 1.9 comes with Binding#eval. In 1.8.6 you can do this:

class Binding
def eval(str)
Kernel.eval(str, self)
end
end

a = 10
b = 12
binding.eval('a + b') # => 22

def another(c, d)
binding.eval('c + d')
end
another(20, 22) # => 42

Regards,
Sean

I thought in 1.8.6 it could be done.. Not positive though

a, b = 3, 5
formula="a*b"
p eval(formula)
 
S

Sean O'Halpin

I thought in 1.8.6 it could be done.. Not positive though

a, b = 3, 5
formula="a*b"
p eval(formula)
D'oh. You're absolutely right. Maybe I was thinking of this:

a = 1
b = 2
def some_eval(context)
eval('a + b', context)
end

some_eval(binding) # => 3

Late night. Off to bed :)

Regards,
Sean
 
R

Robert Klemme

2009/2/2 Damjan Rems said:
Just an idea which may come in handy. Can this be done and how in Ruby.

def calc(what)
some_eval(what)
end

a=10
b=12
calc('a+b') # expression as parameters
=> 12 # would return

a='aa'
b='bb'
calc('a+b')
=> 'aabb'

This is of course strictly hypothetical. I would like the expression to
be evaluated inside the method using variables which are local to the
calling part.

As has been demonstrated you need the binding of the context in which
you want to evaluate your expression string. I see two options.

1. explicitly, i.e.

def calc(what, bind)
eval(what, bind)
end

but this is pointless as "calc" is just an alias for "eval".

2. implicitly

You can keep track of bindings by implementing a trace function (see
set_trace_func). Argument 4 is the current binding and you can place
them in a thread local stack, e.g.

# untested
set_trace_func lambda {|*a|
case a.first
when /call$/
(Thread.current[:bindings] ||= []).push(a[4])
when /return$/
Thread.current[:bindings].pop
end
}

def calc(s)
eval(s, Thread.current[:bindings][-2])
end

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top