Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用包含的多个模块的相同名称执行方法_Ruby_Inheritance_Module - Fatal编程技术网

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

Ruby 使用包含的多个模块的相同名称执行方法,ruby,inheritance,module,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 它

我有两个方法名相同的模块。当我在某个类中包含这两个模块时,只执行最后一个模块的方法。我需要在初始化类时执行这两个命令:

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

它可行吗?

正如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

行“FirstModule.instance\u method…”可以用简单的“foo”来代替,但是通过显式,您可以确保无论发生什么,您都是从您认为是从该mixin调用该方法的。

您可以修改包含的模块吗?也许您只需在第二个模块中调用
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
或者你真的想这么做

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

请参阅“可行?”-没有一些元编程巫术就不行。您需要
包含这些模块吗?我想不会。事实上,#bind方法对此相当挑剔,只允许将未绑定的方法绑定到同一类的对象。因此,如果您想在不执行include的情况下进行绑定,您需要一些额外的魔法使其“可行”,例如重新定义#bind方法本身^ ^ ^ ^那么您的意思是,
bind
是一种受保护的方法?我没有意识到那一点。很高兴知道。不,它是UnboundMethod类的公共实例方法。但是,如果其参数(方法绑定到的对象)与方法解除绑定的对象不属于同一类,则会引发错误。我认为,这些未绑定的方法的目的正是使人们有可能通过模块继承、解析继承菱形等来实现。实际上,我认为这种限制过于严格,如果绑定的对象是相同的鸭子类型,则应该足够了。但是,去说服Matz在香草绑定方法中允许这种危险的东西,让它得到官方认可。当然,我可以修改模块,它们是我的,你的解决方案非常有效。thanksA有点脆弱,严格来说,你回答的问题与被问到的问题略有不同,但你的解决方案是可行的,投你一票。@SanTiago:这并不像你想的那么明显。既然模块是你的,你确定你只是不想写
模块M1;def棒;p:M1端;模块M2;包括M1、def foo;p:M2端部;SC级;包括M1;def初始化;foo end end
?@BorisStitnicky更好,我喜欢它,不确定OP对此有何想法请确保调用
super(如果已定义)(super)
,否则您不能包含
M2
,而不包含
M1
,或者在超类中的某个地方定义
foo