From: Robert Klemme Date: 2008-04-20T22:30:04+09:00 Subject: Re: Executing code in a variable On 20.04.2008 14:50, David A. Black wrote: > Hi -- > > On Sun, 20 Apr 2008, christiantheilhave@gmail.com wrote: > >> On Apr 20, 11:43 am, Zangief Ief wrote: >>> Hello, >>> >>> I have a Ruby code stocked into a Ruby variable like this: >>> >>> buffer = ' puts "Hello World!" ' >>> >>> Is there a way for execute the current code by using buffer variable ? >>> >>> Thanks >>> -- >>> Posted viahttp://www.ruby-forum.com/. >> Sure, you can use eval, eg. >> >> irb(main):002:0> eval 'puts "Hello world"' >> Hello world >> => nil >> >> However, eval should be usually avoided. Instead Ruby has the methods >> instance_eval, class_eval and module_eval, which works the same as >> eval but the argumented is executed in the scope of the current object/ >> class/module. > > The main advantage of instance/class/module_eval over eval, though, is > that they can take a block and therefore you don't have to evaluate a > string. If you do this: > > obj.instance_eval(str) > > it's no better or worse, from the point of view of safety, than using > eval. It is slightly better because with #instance_eval you can control what "self" is set to and avoid a certain class of issues: irb(main):001:0> class Foo irb(main):002:1> attr_accessor :bar irb(main):003:1> def work1(s) irb(main):004:2> eval s irb(main):005:2> end irb(main):006:1> def work2(s) irb(main):007:2> Object.new.instance_eval(s) irb(main):008:2> end irb(main):009:1> end => nil irb(main):010:0> f=Foo.new => # irb(main):011:0> f.bar="important" => "important" irb(main):012:0> f.work2 "@bar='messed'" => "messed" irb(main):013:0> f.bar => "important" irb(main):014:0> f.work1 "@bar='messed'" => "messed" irb(main):015:0> f.bar => "messed" irb(main):016:0> But this is just a gradual difference - there is still enough damage that can be done by evaluating strings or arbitrary code. irb(main):016:0> f.work2 "puts 'ooops!';exit 1" ooops! robert@fussel ~ Kind regards robert