Если вы передаете что-либо, что вы получаете извне, на eval
, вы делаете что-то не так, и это очень неприятно. очень трудно избежать кода, достаточного для того, чтобы он был безопасным, поэтому я считаю его довольно небезопасным. Однако, если вы используете eval, чтобы избежать дублирования или других подобных вещей, например, в следующем примере кода, все будет в порядке.
class Foo
def self.define_getters(*symbols)
symbols.each do |symbol|
eval "def #{symbol}; @#{symbol}; end"
end
end
define_getters :foo, :bar, :baz
end
Однако, по крайней мере в Ruby 1.9.1, в Ruby есть действительно мощные методы метапрограммирования, и вы могли бы вместо этого сделать следующее:
class Foo
def self.define_getters(*symbols)
symbols.each do |symbol|
define_method(symbol) { instance_variable_get(symbol) }
end
end
define_getters :foo, :bar, :baz
end
В большинстве случаев вы хотите использовать эти методы, и экранирование не требуется.
Другая плохая вещь в eval
заключается в том, что (по крайней мере, в Ruby) он довольно медленный, поскольку интерпретатору необходимо проанализировать строку, а затем выполнить код внутри текущей привязки. Другие методы вызывают функцию C напрямую, и поэтому вы должны получить значительное ускорение.