Advanced Ruby: Eval over multiple Bindings?

This is an extremely advanced Ruby question. Given:

def binding1
a = 1
binding
end

def binding2
b = 2
binding
end

eval(‘a’, binding1) #=> 1
eval(‘b’, binding2) #=> 2

Is there a way to “merge” the binding to do something like:

eval(‘a + b’, binding1 + binding2) #=> 3

The only method directly on binding is eval, so you’d have to do it in
some sort of manual fashion.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 12.11.2011 21:19, schrieb Intransition:

Is there a way to “merge” the binding to do something like:

eval(‘a + b’, binding1 + binding2) #=> 3

Not sure if that’s exactly what you want, but this works:

binding1.eval(“a + binding2.eval(‘b’)”) #=> 3

This is not ‘merging’ the two bindings, it rather opens the second
binding inside the first one.

Regarding Binding#eval, is there a specific reason why it can’t take a
block instead of a string, the same way e.g. Module#instance_eval does?

Vale,
Marvin
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOvuB4AAoJELh1XLHFkqha8J4H/j5bp6DYVoSrwJoIk+pXQ1pI
j98OCgUTmjZDED3C2EJ5y1SEPrDwGQ22pDtfExIWvpIz9GH2BAUVTRip+LyZmzJy
wJhn3CuKnwUvvsZukzgTn0kPwkCSUGRo6oxVKf5bKC1P3oU2H2qAlYoK2J1G1yHb
nOEB+uGwPr+kDphwZeEbeNX8vO7ZyepMv5Zoiq1m+DlvHPPwFadZWX4Cwqhot5OZ
EGT0J6R4slLW29ys1uxaoVScm9d/7POa9khqwUl7hiyWSdvHn38MOByD/e2tM8Sz
PjdoBwgnfGreWOAmyjQYSrSJfiHmVeUTFb8Cphv/COPulo9MkyNJes5AGkigpn0=
=8CNX
-----END PGP SIGNATURE-----

On Saturday, November 12, 2011 4:10:09 PM UTC-5, Quintus wrote:

binding1.eval(“a + binding2.eval(‘b’)”) #=> 3

This is not ‘merging’ the two bindings, it rather opens the second
binding inside the first one.

My usecase is for template generation. For example ERB, it’s render
method
takes a Binding.

Regarding Binding#eval, is there a specific reason why it can’t take a
block instead of a string, the same way e.g. Module#instance_eval does?

Actually I suggested that feature on ruby issue tracker and I believe
the
anwser given was YAGNI.

If it were possible could it solve this?

There doesn’t seem to be a way to ‘merge’ the bindings, but there
are ways around it, I bet. This is kinda hacky but it works for
this simple case at least:

class Binding

def +(other)
raise “Other has to be a binding” unless Binding === other
values = []
instance_variables.each do |iv|
values << "#{iv[1…-1]} = #{instance_variable_get(iv)}; "
end
other.instance_variables.each do |iv|
values << "#{iv[1…-1]} = #{other.instance_variable_get(iv)}; "
end
binding.tap do |bind|
bind.eval values.join
end
end

end

class Test
def binding1
a = 1
binding.tap do |_b|
local_variables.each do |lv|
_b.instance_variable_set("@#{lv}", _b.eval(lv.to_s)) unless lv
=~ /_b/
end
end
end

def binding2
b = 2
binding.tap do |_b|
local_variables.each do |lv|
_b.instance_variable_set("@#{lv}", _b.eval(lv.to_s)) unless lv
=~ /_b/
end
end
end

end

t = Test.new

puts eval(‘a + b’, t.binding1 + t.binding2) # => 3

hahah, at least I tried.

-Luke

On Sat, Nov 12, 2011 at 4:17 PM, Intransition [email protected]
wrote:

Not sure if thats exactly what you want, but this works:

I needed it once, while trying to write a tool for acceptance tests. Gave
up on it b/c this feature didn’t exist.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 12.11.2011 23:17, schrieb Intransition:

If it were possible could it solve this?

I don’t think so. I just wondered.

Vale,
Marvin

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOv4XrAAoJELh1XLHFkqhaoUMH/1SllyWhU/OuTrxniv/nTQ4a
H2GnuTB5tIMhNEv7EeJnCdZXO70UHooVWHDMRbPNj1pSDhxAnQQ8/6MWiSywYaiK
hnfA4He2Hjs4sRwChuL40HG8/91XBqz5vEAwhtCoX/VLCbAh7SZ8sBjOIVDatCRD
pWZVusSzMqaxmeUtHfGIQ+dmFd1n0zQQCNftY11YunGutso7OzpZ+g7KAbz3CIzp
c3yX3qbKfxMRE7qRSMFSFwBisXix+o8mbwykh8Nxnze0y4ltiw/kTVeQh7k8u6DM
9YDDio65Ga7hBqsjzIL34GeQMnzrRrWXbaIWV2mBJC7tF3EfgZAhygZzv6yypzc=
=uO6U
-----END PGP SIGNATURE-----

Da: Intransition [mailto:[email protected]]
Inviato: sabato 12 novembre 2011 21:20
A: ruby-talk ML; [email protected]
Oggetto: Advanced Ruby: Eval over multiple Bindings?

This is an extremely advanced Ruby question. Given:

def binding1
a = 1
binding
end

def binding2
b = 2
binding
end

eval(‘a’, binding1) #=> 1
eval(‘b’, binding2) #=> 2

Is there a way to “merge” the binding to do something like:

eval(‘a + b’, binding1 + binding2) #=> 3


Caselle da 1GB, trasmetti allegati fino a 3GB e in piu’ IMAP, POP3 e
SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Conto Arancio al 4,20%. Soldi sempre disponibili, zero spese, aprilo in
due minuti!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11923&d=29-12

-----Messaggio originale-----
Da: Quintus [mailto:[email protected]]
Inviato: domenica 13 novembre 2011 09:56
A: ruby-talk ML
Oggetto: Re: Advanced Ruby: Eval over multiple Bindings?

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 12.11.2011 23:17, schrieb Intransition:

If it were possible could it solve this?

I don’t think so. I just wondered.

Vale,
Marvin

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOv4XrAAoJELh1XLHFkqhaoUMH/1SllyWhU/OuTrxniv/nTQ4a
H2GnuTB5tIMhNEv7EeJnCdZXO70UHooVWHDMRbPNj1pSDhxAnQQ8/6MWiSywYaiK
hnfA4He2Hjs4sRwChuL40HG8/91XBqz5vEAwhtCoX/VLCbAh7SZ8sBjOIVDatCRD
pWZVusSzMqaxmeUtHfGIQ+dmFd1n0zQQCNftY11YunGutso7OzpZ+g7KAbz3CIzp
c3yX3qbKfxMRE7qRSMFSFwBisXix+o8mbwykh8Nxnze0y4ltiw/kTVeQh7k8u6DM
9YDDio65Ga7hBqsjzIL34GeQMnzrRrWXbaIWV2mBJC7tF3EfgZAhygZzv6yypzc=
=uO6U
-----END PGP SIGNATURE-----


Caselle da 1GB, trasmetti allegati fino a 3GB e in piu’ IMAP, POP3 e
SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Conto Arancio al 4,20%. Zero spese e massima liberta’, aprilo in due
minuti!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11922&d=29-12