如果一个类包含许多模块,并且从包含来自其原始模块的include调用私有方法,并且私有方法存在于具有相同名称的其他模块中,则它应该使用其自己的模块中的定义。在代码中:
module C
def c
puts collision
end
private
def collision
'c'
end
end
module B
def b
puts collision
end
private
def collision
'b'
end
end
class A
include B
include C
end
A.new.b
# => 'c'
我希望A.new.b
能够'b'
和A.new.c
提供'c'
,但会发生冲突,因为它们使用相同的私有方法名称。在包含许多包含的大型项目中,如何避免这种情况?
答案 0 :(得分:2)
你期待一些魔法,但不存在。
include
是一个普通的好混合。一旦被调用,它只是将包含模块中声明的所有方法“插入”到调用include
的模块中。
因此你最终得到了类似的东西:
class A
public
def c; ... end
private
def collision; ... end
public
def b; ... end
private
def collision; ... end
end
由于ruby开放类概念,后一个私有方法collision
显然优先于前者。
答案 1 :(得分:1)
我认为真正的问题是:我如何确保我的模块没有使用其他模块方法(这些方法意外地具有相同的名称)。
如果您可以确保模块方法不依赖于状态并将它们定义为模块方法并以这种方式使用它,那将是最好的。因此,您明确使用任何helping
方法,如下所示:
module C
def c
puts C.collision
end
def self.collision
'c'
end
end
module B
def b
puts B.collision
end
def self.collision
'b'
end
end
class A
include B
include C
end
A.new.b # b
A.new.c # c
如果您想将它们设为私有,可以使用一些额外的代码,您可以阅读一篇明确的文章:https://6ftdan.com/allyourdev/2015/05/02/private-module-methods-in-ruby/
正如this answer中所述,你可以开启它以使其发挥作用。包含机制非常简单,(IMO)它应该保持这种方式。当你意识到这个碰撞问题时 - 你现在可以避免它。
如果您不喜欢这种方法,您还可以将实际工作封装在一个类中,并使用模块进行包含:
module C
def c
MyLibStuff::ClassDoingRealWork.no_collision_here_anymore(any, param, if_needed)
end
end