检查mixee类上是否定义了方法?

时间:2015-03-20 19:03:03

标签: ruby-on-rails ruby

我们有一个处理取消模型的模块。它很干净,效果很好,但是我们已经遇到了一个问题,我们想把它混合在一起,已经定义了我们的模块方法(cancel!等)。

我们尝试提出新名称以避免碰撞,但一切似乎都不太理想,我们喜欢调用cancel!的干净。所以,我们决定做一些像:

def cancel!
  cancelly_stuff
  if class.parent.respond_to(:cancel!) super
end

但是,它是一个模块,因此我们将其混入的课程不是class.parent。我无法谷歌如何引用模块的mixee类。

2 个答案:

答案 0 :(得分:1)

请问是否超级定义:

def cancel!
  cancelly_stuff
  super if defined?(super)
end

Avdi Blog

的更多信息

修改:我添加了一个正在运行的示例:

# 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

我希望它对您的问题有帮助。

相关问题