此问题已在此处有答案:
When monkey patching an instance method, can you call the overridden method from the new implementation?(3个答案)
4天前关闭。
为什么我没有得到'init'字符串?
class Dwa
attr_reader :nazwa
def initialize()
puts 'init'
@nazwa = "dwa"
end
end
class Dwa #open this same object definition
def initialize()
super #or super()
@nazwa = "trzy"
end
end
d = Dwa.new
puts "#{d.nazwa}"
我再次打开对象并重新定义initialize
。
当我用未修改的类运行代码时,我打印init
和dwa
如何修改initialize
并仍然运行puts 'init'
我期望:
$ run.rb
init
trzy
3条答案
按热度按时间mspsb9vt1#
主要问题是重新开放
Dwa
并重新定义initialize
将取代旧的initialize
。由于super
只适用于引用超类,因此在这种情况下它是无用的。要调用旧的行为,您必须将旧的
initialize
方法存储在某个地方,并从新定义中调用它。一种方法是使用instance_method
获取UnboundMethod
并将其存储在变量中。然后从initialize
的重新定义调用它(使用bind_call
)。我们在这里使用
define_method :initialize
而不是def initialize
的原因是上下文切换。将define_method :initialize
与一个块一起使用允许我们访问外部的old_initialize
变量,这在def initialize
中是不可能的。或者,您可以更改类结构/层次结构,并使用
Dwa
作为其超类定义一个新类。aiqt4smr2#
为什么我没有得到'init'字符串?
Doe
的超类是Object
。Object#initialize
不打印任何东西,因此您不会得到任何打印输出。modyfy如何初始化并仍然运行将'init'
hmae6n7t3#
如果您决定重写此方法,为什么不完全显式地重写它呢?
也许这是最好的选择
但如果你还想一些黑客,你可以使用别名