Forum: Ruby Reffering back to caller's binding

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.
A44df35268bd9586ce9328f0fe0313ec?d=identicon&s=25 Owein Herrmann (owein)
on 2009-04-18 19:16
Hello Rubyists,

I am trying to define a helper method which displays a ruby expression
and then displays the results of that expression via puts. Initially I
did this, which obviously did not work:

def peval( expression )
  puts expression
  puts eval( expression )
  puts ""
end

of course when I ran it, the scope of the method does not include
objects in the calling scope... so then I realized it had to do with
bindings and I defined this:

def peval
  f,b = yield
  puts f
  puts eval(f,b)
  puts ""
end

and this works, but, its really ugly:

peval { ["map.inspect", binding()] }

so my question is, is there a way to obtain the caller's binding so that
I do not have to specify it in the call? Is this in Pickaxe and I spaced
out on that section? I eally just want to be able to specify the
expression (in quotes), get it to display, see the results, move on...
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-04-19 03:10
(Received via mailing list)
On Sat, Apr 18, 2009 at 6:16 PM, Owein Herrmann <oherrmann@gmail.com>
wrote:
> end
> end
>
> and this works, but, its really ugly:
>
> peval { ["map.inspect", binding()] }
>
> so my question is, is there a way to obtain the caller's binding so that
> I do not have to specify it in the call? Is this in Pickaxe and I spaced
> out on that section? I eally just want to be able to specify the
> expression (in quotes), get it to display, see the results, move on...

Explicitly specify the block parameter and use its #binding method to
get the binding for where the block was defined, i.e.

def peval(&block)
 f,b = block.call
 puts f
 puts eval(f,block.binding)
 puts ""
end

peval { ["var.inspect"] }

OUTPUT:
var.inspect
[1, 2, 3]

Regards,
Sean
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-04-19 03:12
(Received via mailing list)
On Sun, Apr 19, 2009 at 2:10 AM, Sean O'Halpin <sean.ohalpin@gmail.com>
wrote:
>>  puts ""
>>  puts ""
>
> peval { ["var.inspect"] }
>
> OUTPUT:
> var.inspect
> [1, 2, 3]
>
> Regards,
> Sean
>

I leave it as an exercise for the reader to work out the definition of
'var' ;)
87ef5d1e14b148eb596433bc17ffe690?d=identicon&s=25 Leo (Guest)
on 2009-04-19 07:36
(Received via mailing list)
> peval { ["var.inspect"] }

Interesting solution. The solution would be even better if ruby had a
Proc#to_str method built in or if #to_a returned a sexpr (à la lisp)
that could be easily manipulated, printed, and evaluated.
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-04-19 12:41
(Received via mailing list)
On Sun, Apr 19, 2009 at 6:36 AM, Leo <minilith@gmail.com> wrote:
>> peval { ["var.inspect"] }
>
> Interesting solution. The solution would be even better if ruby had a
> Proc#to_str method built in or if #to_a returned a sexpr (à la lisp)
> that could be easily manipulated, printed, and evaluated.

I agree - it would be nice if this was built-it. However, you can get
it with ParseTree:

require 'ruby2ruby'
require 'parse_tree_extensions'
def dump(&block)
  puts block.to_ruby.gsub(/^proc\s*\{(.*)\}$/, '\1').strip
  puts block.call
end
# need to call to_ruby on a method before the to_ruby call will work on
blocks
def __dummy__
end
method(:__dummy__).to_ruby

var = [1,2,3]
dump { var.inspect }
#> var.inspect
#> [1, 2, 3]

# also, just to show you can do this too:
p proc { 1 + 1 }.to_sexp
#> s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:call, s(:lit,
1), :+, s(:arglist, s(:lit, 1))))


Regards,
Sean
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2009-04-19 22:29
(Received via mailing list)
On Apr 19, 2009, at 03:41 , Sean O'Halpin wrote:

> I agree - it would be nice if this was built-it. However, you can get
> it with ParseTree:
>
> require 'ruby2ruby'
> require 'parse_tree_extensions'
> def dump(&block)
>  puts block.to_ruby.gsub(/^proc\s*\{(.*)\}$/, '\1').strip
>  puts block.call
> end

except that PT is essentially dead because it can't work on 1.0...
A44df35268bd9586ce9328f0fe0313ec?d=identicon&s=25 Owein Herrmann (owein)
on 2009-04-20 00:56
Fabulous! Thank you so much for the help!
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2009-04-20 01:16
(Received via mailing list)
On Sun, Apr 19, 2009 at 9:28 PM, Ryan Davis <ryand-ruby@zenspider.com>
wrote:
>>  puts block.call
>> end
>
> except that PT is essentially dead because it can't work on 1.0...

I'm in denial :/
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2009-04-20 14:00
(Received via mailing list)
On Apr 19, 2009, at 16:14 , Sean O'Halpin wrote:

>> except that PT is essentially dead because it can't work on 1.[9]...
>
> I'm in denial :/

have fun with that. I hope it works well for you.
This topic is locked and can not be replied to.