如何使用class_eval? [英] How do I use class_eval?
问题描述
我不理解class_eval
.
class Module
def attr_ (*syms)
syms.each do |sym|
class_eval %{def #{sym}= (val)
@#{sym} = val
end}
end
end
end
%
是什么意思?
class_eval
的作用是什么?
(val)
是哪里来的?
推荐答案
简短的答案是:您可能想像这样使用class_eval
避免.
The short answer is: you probably want to avoid using class_eval
like this.
以下是您的代码的说明:
Here's an explanation of your code:
%{hello}
只是在Ruby中编写字符串文字的另一种方式,而不必担心在字符串中转义双引号或单引号:
The %{hello}
is just another way to write a string literal in Ruby, without having to worry about escaping double or single quotes within the string:
%{hello "world"} == "hello \"world\"" # => true
代码中的val
是所定义方法的参数.
The val
in your code is an argument of the method being defined.
class_eval
用于定义一些方法,方法是计算将要编写的文本以编写定义,然后对其求值.顺便说一句,这里没有必要.等效的代码为:
The class_eval
is used to define some methods by computing the text one would write to do the definition and then evaluating it. It is not necessary here, BTW. An equivalent code would be:
class Module
def attr_ (*syms)
syms.each do |sym|
define_method "#{sym}=" do |val|
instance_variable_set "@#{sym}", val
end
end
end
end
这等效于内置的attr_writer
.
更新:两者之间实际上可能存在显着差异……
Update: There can actually be a significant difference between the two...
如果您不信任参数syms
,则class_eval
版本很容易受到攻击.例如:
The class_eval
version is vulnerable if you can't trust the argument syms
. For example:
class Foo
attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val"
end
class_eval
版本将打印两次我可以在这里执行任何操作",证明它可以执行任何操作. define_method
版本不会打印任何内容.
The class_eval
version will print "I can execute anything here" twice, proving it can execute anything. The define_method
version won't print anything.
This type of code was pivotal to create major vulnerability for all installed Rails apps.
这篇关于如何使用class_eval?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!