dav*_*k01 3 ruby monkeypatching metaprogramming
我有点困惑为什么以下代码实际工作:
String.instance_eval do # self is set to String
[:readlink, :symlink?, :expand_path].each do |method| # self is still String
define_method(method) do # self is still String
File.send(method, self) # what exactly is this self?
end
end
end
"asdf".expand_path # => "C:/users/some_user/asdf"
Run Code Online (Sandbox Code Playgroud)
我不明白为什么最后一行有效.当每个方法定义的方法体不等同于File.send(method, String)?上述块中没有一个实际发生变化self.唯一更改的行self是String.instance_eval,它会更改self为String.
File.send(method, self)
Run Code Online (Sandbox Code Playgroud)
这self将在将调用动态生成的方法时进行评估.此时它将被设置为String的实例.(在你的例子中是"asdf").
它实际上相当于打开String类并手动编写所有这些方法.
class String
def readlink
File.send :readlink, self
end
def expand_path
File.send :expand_path, self
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |