From: "Mauricio Fernández" Date: 2002-08-24T22:29:40+09:00 Subject: Re: eval in class method On Sat, Aug 24, 2002 at 09:22:41PM +0900, michael libby wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hi. I'm not seeing what I thought would happen with some eval code, here is > a sample via irb: > > chandler@greyhound:~$ irb > irb(main):001:0> class FooBar > irb(main):002:1> def baz > irb(main):003:2> puts "foobar:baz" > irb(main):004:2> end > irb(main):005:1> end > nil > irb(main):006:0> f = FooBar.new > # > irb(main):007:0> f.baz > foobar:baz > nil > > OK. So far so good, simply made a test class and ran a method from it. > > irb(main):009:0> eval("class FooBar\ndef baz\nputs 'foobar:new > baz'\nend\nend") > nil > irb(main):010:0> f.baz > foobar:new baz > nil > > OK. So far even better. Use eval to redefine method. > > irb(main):011:0> class FooBar > irb(main):012:1> def rebaz > irb(main):013:2> eval("class FooBar\ndef baz\nputs > 'foobar:rebaz'\nend\nend") > irb(main):014:2> end > irb(main):015:1> end > nil > irb(main):016:0> f.rebaz > nil > > So far nothing seems amiss. Instead of doing eval from main script, wrote > rebaz method to do eval as instance method. > > irb(main):017:0> f.baz > foobar:new baz > nil > > Sigh. After calling #rebaz which I thought would have changed #baz, #baz > still acts the same-- even though, except for scope/context, the eval > statement was the same exact statement as I used before, where #baz did > change. > > How can I write an instance method that will get the eval done the way I > thought it was going to work? I don't want to eval dependent on FooBar > class, the eval might want to change a method in Gizmo or Widget class > instead. Eval just needs to happen from FooBar since that is the class > that will have the method to handle evaluation of new code. Any > suggestions? > batsman@kodos:~/src/rubylang$ cat class_eval.rb class FooBar def baz puts "FooBar::baz" end def on_me FooBar.class_eval <<-EOF def baz puts "Redefined FooBar::baz" end EOF end def on_another( aclass ) aclass.class_eval <<-EOF def baz puts "Redefined #{aclass.to_s}::baz" end EOF end end class Bar def baz puts "Bar::baz" end end f = FooBar.new b = Bar.new f.baz b.baz f.on_me f.baz f.on_another Bar b.baz batsman@kodos:~/src/rubylang$ ruby class_eval.rb FooBar::baz Bar::baz Redefined FooBar::baz Redefined Bar::baz batsman@kodos:~/src/rubylang$ -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com It's easy to get on the internet and forget you have a life -- Topic on #LinuxGER