执行包含多个模块的相同名称的方法

San*_*ago 5 ruby inheritance module

我有两个模块具有相同的方法名称.当我在某个类中包含两个模块时,只执行最后一个模块的方法.我需要在初始化类时执行它们:

class MyClass
    include FirstModule
    include SecondModule

    def initialize
        foo # foo is contained in both modules but only the one in SecondModules is executed
    end
end
Run Code Online (Sandbox Code Playgroud)

它可行吗?

Bor*_*cky 10

正如Yusuke Endoh所说,Ruby中的一切都是可行的.在这种情况下,你必须忘记只是说"foo"的便利性,你必须非常清楚你真正想做的事情,比如:

class MyClass
  include FirstModule
  include SecondModule
  def initialize
    FirstModule.instance_method( :foo ).bind( self ).call
    SecondModule.instance_method( :foo ).bind( self ).call
  end
end
Run Code Online (Sandbox Code Playgroud)

"FirstModule.instance_method ......"这一行可以简单地用"foo"代替,但是通过明确表示,无论如何,你都要确保从混合中调用方法,你认为这样做.

  • 实际上,#bind方法非常挑剔,并允许您仅将未绑定的方法绑定到同一个类的对象.因此,如果你想绑定withoud做包含,你需要一些额外的魔法来使它"可行",比如重新定义#bind方法本身^ _ ^ (2认同)
  • 不,它是UnboundMethod类的公共实例方法.但是如果它的参数(绑定方法的对象)与方法未绑定的对象不是同一个类,则会引发错误.我认为这些未绑定方法的目的正是为了让人们能够利用模块继承,解决继承钻石等问题. (2认同)
  • 我实际上认为这有点过于严格的限制,我认为如果该方法绑定的对象具有相同的_duck_类型应该足够了,但是去说服Matz通过允许它来对这些危险的东西给予官方点头在香草#bind方法^ _ ^ (2认同)

小智 7

你能修改包含的模块吗?也许你只是打电话super给第二个模块?

module M1
  def foo
    p :M1
  end
end

module M2
  def foo
    p :M2
    defined?(super) && super
  end
end

class SC
  include M1
  include M2

  def initialize
    foo
  end
end

SC.new
Run Code Online (Sandbox Code Playgroud)

或者你真的想要这样做?

module M1
  def bar; p :M1 end
end

module M2
  include M1
  def foo; bar; p :M2 end
end

class SC
  include M2
  def initialize; foo end
end
Run Code Online (Sandbox Code Playgroud)

在这里查看现场演示