Now blah responds to some_method. Is there way to include methods
without eval?
You must understand that there is nothing wrong in #eval, this is just
that some times #eval is evil
You have, mainly, 2 form for #eval
* eval "some_string"
if you *trust completely* (for example you have hardcoded it in the
script) the string there is no problem.
It can exist a problem when you try to use #eval with any strings (even
strings that you don't know the content) and this is where reside the
evil side of #eval, because eval is very powerfull and can do anything.
In this case you can always try to protect you with $SAFE, something
like this
Thread.new do
$SAFE = 4
eval string
end.join
* eval { ... }
If you use this form, you have fatally hardcoded the block and this mean
that you can, perhaps, trust it.
#eval is powerfull, but it's sometimes too powerfull (its evil side) or
overkill and in many cases you can just use another form, like __send__
For you example you can write
pigeon% cat b.rb
#!/usr/bin/ruby
some_class = Struct.new( 'SomeClass', 'some_field' )
blah = some_class.new( 'anything' )
module Feature
def some_method
puts "some_method"
end
end
Feature.__send__(:append_features, some_class)
blah.some_method
pigeon%
pigeon% b.rb
some_method
pigeon%
You just want to use include, no need for the evil eval just send the
method #append_features to the module
Use the evil eval only when it don't exist another way to do it and when
it's secure to use this evil eval
Guy Decoux