我有点困惑为什么以下代码实际上有效:
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"
我不明白为什么最后一行有效。定义每个方法时,该方法的主体是否等同于File.send(method, String)
?上述块中没有一个实际更改self
。唯一更改self
的行为String.instance_eval
,并将self
更改为String
。
答案 0 :(得分:5)
File.send(method, self)
当调用动态生成的方法时,将评估此self
。此时它将被设置为String的实例。 (在你的例子中是“asdf”)。
它实际上相当于打开String
类并手动编写所有这些方法。
class String
def readlink
File.send :readlink, self
end
def expand_path
File.send :expand_path, self
end
end