class Person
include Voice
include Beep
end
module Voice
def speak
puts 'speaking from module'
end
def original_speak
# ???
end
end
module Beep
def speak
puts 'beep beep'
end
end
如何致电Voice#speak
?例如:
Person.new.voice_speak
我想将此代码添加到Voice模块,而不是Person类或Beep模块。
用例:
执行软删除的模块:
module Undeletable
def delete
# mark document as deleted. This creates a deletion document.
end
def restore
# Delete (for real) the deletion.
end
def obliterate
restore # because we don't want orphaned deletions.
real_delete # This should call Mongoid#delete
end
end
def Foo
include Mongoid::Document
include Undeletable
end
所以,一般来说,当我们调用foo.delete时,我们想要软删除。但是,在极少数情况下,我们希望进行真正的删除。该模块应该支持这两种方法。
答案 0 :(得分:1)
读者:我把这个答案发给了原来的问题。随后问题发生了变化。如果有兴趣,请查看上下文的编辑历史记录。
步骤如下。
Voice
中包含模块时调用的模块Person
中创建回调。 (class)方法是Module#included,它有一个参数,类包括模块。Included
创建original_speak
的{{1}}别名(Person.speak
)。必须首先执行此操作,而Person
是最初在Person#speak
上定义的方法speak
。 Person
然后使用Module#remove_method(不是Module#undef_method)删除(原始)实例方法Included
,导致Person#speak
成为实例方法{{ 1}},实际上是正确的"背后"在移除后者之前的原始Person#speak
。
Voice#speak
答案 1 :(得分:1)
我认为最简单的方法是在函数中添加一个覆盖delete
的函数。例如:
module Undeletable
def delete(call_super=false)
return super if call_super
return "some custom response"
end
def obliterate
delete(true)
end
end
此处super
关键字非常重要。如果某个方法被另一个方法覆盖,则super
可以调用原始方法。也可以将参数传递给super
。