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ます。

4

1 に答える 1

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
于 2012-10-23T18:40:22.633 に答える