Ruby: Monkey patching String class
-
13-07-2021 - |
Domanda
I am a little confused why the following piece of code actually works:
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"
I don't understand why the last line works as it does. When each method is defined isn't the body of the method equivalent to File.send(method, String)
? None of the above blocks actually change self
. The only line that changes self
is String.instance_eval
and it changes self
to String
.
Soluzione
File.send(method, self)
This self
will be evaluated when that dynamically generated method will be called. At that point it will be set to an instance of String. ("asdf" in your example).
It's actually equivalent to opening String
class and writing all those methods manually.
class String
def readlink
File.send :readlink, self
end
def expand_path
File.send :expand_path, self
end
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow