Ruby:访问对象时alias_方法的意外行为
在Ruby中,可以通过多种方式重新定义方法。一个是打开本征类或单例类,另一个是使用Ruby:访问对象时alias_方法的意外行为,ruby,Ruby,在Ruby中,可以通过多种方式重新定义方法。一个是打开本征类或单例类,另一个是使用instance\u eval。但是,alias_方法仅在本征类上可用。为什么会这样,或者有没有一种方法可以将它与instance\u eval一起使用 class << ENV # works alias_method :original_brackets, :[] # works def [](name) # ... end end ENV.instance_eval
instance\u eval
。但是,alias_方法
仅在本征类上可用。为什么会这样,或者有没有一种方法可以将它与instance\u eval
一起使用
class << ENV
# works
alias_method :original_brackets, :[]
# works
def [](name)
# ...
end
end
ENV.instance_eval do
# raises NoMethodError
alias_method :original_brackets, :[]
# works
def [](name)
# ...
end
end
类是模块
类的一部分。在instance\u eval
的块中,self
是ENV
对象,不能访问模块
方法
ENV.instance_eval do
p self.class
end
#=> Object
通常,您可以使用以下技术在instance\u eval
中为方法别名:
class Foo
def bar
end
end
p Foo.instance_methods(false)
#=> [:bar]
Foo.new.instance_eval do
self.class.send :alias_method, :bar_orig, :bar
end
p Foo.instance_methods(false)
#=> [:bar, :bar_orig]
在上述情况下,send
必须用作alias\u方法
是私有方法,在类/模块定义之外不可访问
但是,ENV
不是任何特殊用途类(如Foo
)的实例,而是添加了许多单例方法的对象的实例。因此,上述技术将不起作用,相反,您必须使用ENV
对象的singleton
类添加别名
以下是如何做到这一点:
ENV.instance_eval do
singleton_class.send :alias_method, :original_brackets, :[] rescue p "oops"
def [](name)
end
end
或者:
ENV.instance_eval do
class << self
alias_method :original_brackets, :[]
end
def [](name)
end
end
ENV.instance\u eval do
课堂很有趣。这是有道理的。那么我如何在ENV上找到该方法呢?我尝试了ENV.singleton_方法和ENV.singleton_class.methods,但都没有返回:alias_method.Try ENV.class.instance_methods称为singleton classENV.class.methods.sort==ENV.singleton_class.methods.sort#=>true