我们有一个处理取消模型的模块。它很干净,效果很好,但是我们已经遇到了一个问题,我们想把它混合在一起,已经定义了我们的模块方法(cancel!
等)。
我们尝试提出新名称以避免碰撞,但一切似乎都不太理想,我们喜欢调用cancel!
的干净。所以,我们决定做一些像:
def cancel!
cancelly_stuff
if class.parent.respond_to(:cancel!) super
end
但是,它是一个模块,因此我们将其混入的课程不是class.parent
。我无法谷歌如何引用模块的mixee类。
答案 0 :(得分:1)
请问是否超级定义:
def cancel!
cancelly_stuff
super if defined?(super)
end
的更多信息
修改:我添加了一个正在运行的示例:
# calling_super.rb
module Superable
def cancel!
puts 'canceling from module: Superable'
super if defined? super
puts 'end of cancel from module: Superable'
end
end
class WithoutSuper
include Superable
end
class Cancelable
def cancel!
puts 'cancel from class: Cancelable'
end
end
class Child < Cancelable
include Superable
end
at my irb(在1.9.2和2.1.1上测试):
~/rails/learn/ruby (main) > require './calling_super'
=> true
~/rails/learn/ruby (main) > WithoutSuper.new.cancel!
canceling from module: Superable
end of cancel from module: Superable
=> nil
~/rails/learn/ruby (main) > Child.new.cancel!
canceling from module: Superable
cancel from class: Cancelable
end of cancel from module: Superable
=> nil
我认为这是你正在寻找的行为。
答案 1 :(得分:1)
我的帖子有另一个答案,现在使用prepend
代替include
(仅适用于ruby 2.x)。第一个是包括在祖先链的顶端,因为第二个是在课后。
让我们看看它在irb控制台上是如何工作的:
~/rails/learn/ruby (main) > module A
~/rails/learn/ruby (main) | def cancel!
~/rails/learn/ruby (main) | puts 'cancel from m:A'
~/rails/learn/ruby (main) | super if defined? super
~/rails/learn/ruby (main) | end
~/rails/learn/ruby (main) | end
=> :cancel!
~/rails/learn/ruby (main) > class C
~/rails/learn/ruby (main) | prepend A
~/rails/learn/ruby (main) | def cancel!
~/rails/learn/ruby (main) | puts 'cancel from c:C'
~/rails/learn/ruby (main) | end
~/rails/learn/ruby (main) | end
=> :cancel!
~/rails/learn/ruby (main) > C.ancestors
=> [
[0] #<Class:0x000000035421f0>::A,
[1] #<Class:0x000000035421f0>::C < Object,
[2] Object < BasicObject,
[3] PP::ObjectMixin,
[4] Kernel,
[5] BasicObject
]
~/rails/learn/ruby (main) > C.new.cancel!
cancel from m:A
cancel from c:C
=> nil
~/rails/learn/ruby (main) > class D
~/rails/learn/ruby (main) | include A
~/rails/learn/ruby (main) | def cancel!
~/rails/learn/ruby (main) | puts 'cancel from c:D'
~/rails/learn/ruby (main) | super if defined? super
~/rails/learn/ruby (main) | end
~/rails/learn/ruby (main) | end
=> :cancel!
~/rails/learn/ruby (main) > D.ancestors
=> [
[0] #<Class:0x000000035421f0>::D < Object,
[1] #<Class:0x000000035421f0>::A,
[2] Object < BasicObject,
[3] PP::ObjectMixin,
[4] Kernel,
[5] BasicObject
]
~/rails/learn/ruby (main) > D.new.cancel!
cancel from c:D
cancel from m:A
=> nil
我希望它对您的问题有帮助。