gpt4 book ai didi

Ruby:访问对象时 alias_method 的意外行为

转载 作者:太空宇宙 更新时间:2023-11-03 18:10:25 25 4
gpt4 key购买 nike

在 Ruby 中,您可以通过多种方式重新定义方法。一种是打通eigenclass,也就是单例类,还有一种是使用instance_eval。但是,alias_method 仅适用于特征类。为什么会这样,或者有没有办法将它与 instance_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

最佳答案

alias_methodModule 类的一部分。在 instance_eval 的 block 内,selfENV 对象,并且无权访问 Module 方法。

ENV.instance_eval do
p self.class
end
#=> Object

通常,您可以使用以下技术为 instance_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_method 是私有(private)方法,在类/模块定义之外不可访问。


但是,ENV 不是任何特殊用途类(例如 Foo)的实例 - 相反,它是 Object 的实例添加了很多单例方法的类。因此,上述技术将不起作用,您必须使用 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

关于Ruby:访问对象时 alias_method 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35181769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com