nev*_*ame 20 ruby metaprogramming
我不明白class_eval.
class Module
def attr_ (*syms)
syms.each do |sym|
class_eval %{def #{sym}= (val)
@#{sym} = val
end}
end
end
end
Run Code Online (Sandbox Code Playgroud)
什么%意思?
怎么class_eval办?
哪里(val)来了?
Mar*_*une 26
简短的回答是:你可能想避免class_eval像这样使用.
这是您的代码的解释:
这%{hello}只是在Ruby中编写字符串文字的另一种方法,而不必担心在字符串中转义双引号或单引号:
%{hello "world"} == "hello \"world\"" # => true
Run Code Online (Sandbox Code Playgroud)
在val你的代码是被定义的方法的参数.
将class_eval用于通过计算文本一个会写做定义,然后评估它来定义一些方法.BTW,这里没有必要.等效代码是:
class Module
def attr_ (*syms)
syms.each do |sym|
define_method "#{sym}=" do |val|
instance_variable_set "@#{sym}", val
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
这相当于内置attr_writer.
更新:两者之间实际上可能存在显着差异......
class_eval如果你不相信这个论点,那么该版本很容易受到攻击syms.例如:
class Foo
attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val"
end
Run Code Online (Sandbox Code Playgroud)
该class_eval版本将打印"我可以在这里执行任何操作"两次,证明它可以执行任何操作.该define_method版本不会打印任何内容.
此类代码对于为所有已安装的Rails应用程序创建主要漏洞至关重要.