Forum: Ruby Is this possible in Ruby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Be07c8d0d6867fd9a0d525f7d17600e2?d=identicon&s=25 Damjan Rems (ther)
on 2009-02-02 23:49
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
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-02-03 00:34
(Received via mailing list)
On Mon, Feb 2, 2009 at 10:49 PM, Damjan Rems <d_rems@yahoo.com> wrote:
> => 12   # would return
>
> 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
990bf71a4e84e1145a3131f35656dc18?d=identicon&s=25 List Rb (listx300108u79872)
on 2009-02-03 01:12
(Received via mailing list)
On Feb 2, 2009, at 6:33 PM, "Sean O'Halpin" <sean.ohalpin@gmail.com>
wrote:

>> b=12
>> be evaluated inside the method using variables which are local to the
>    Kernel.eval(str, self)
> 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)
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-02-03 01:40
(Received via mailing list)
On Tue, Feb 3, 2009 at 12:12 AM, List.rb <list.rb@gmail.com> wrote:
>
> 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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-02-03 11:06
(Received via mailing list)
2009/2/2 Damjan Rems <d_rems@yahoo.com>:
> => 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
This topic is locked and can not be replied to.