Hi --
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
=> #<Foo:0x7ff7acf4>
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