2012-10-23 31 views
3

我有點困惑,爲什麼下面這段代碼實際工作:紅寶石:猴子打補丁字符串

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

回答

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 
+0

好吧,我的理解是,塊關閉所有變量的定義點。我把「自我」放在了這個變量中,但顯然它具有更多的動態性。 – davidk01