Ruby Rails:Rails如何在两个不同的gem中处理相同的方法名
假设我使用了两个宝石,分别是'A'和'B'。gema定义了模块A,如下所示Ruby Rails:Rails如何在两个不同的gem中处理相同的方法名,ruby,Ruby,假设我使用了两个宝石,分别是'A'和'B'。gema定义了模块A,如下所示 module A def a puts "i am from module A" end end gemb定义模块B,如下所示 module B def a puts "i am from module B" end end 现在我可以将模块B和A包含在C类中 class C include B include A end c = C.new c.a #i am from
module A
def a
puts "i am from module A"
end
end
gemb定义模块B,如下所示
module B
def a
puts "i am from module B"
end
end
现在我可以将模块B和A包含在C类中
class C
include B
include A
end
c = C.new
c.a #i am from module A
现在两个模块都定义了方法
a
。在现实世界中,一个gem中定义的方法名很可能会和另一个gem的方法名发生冲突。在这种情况下,是由开发人员负责处理这种情况,还是Rails(Ruby)提供了一些解决这种情况的方法?如果您能够预测需要解决的冲突,您可以避免冲突或方法践踏。例如,两个不可压缩模块:
module A
def a
:A
end
end
module B
def a
:B
end
end
这两种方法都实现了a
方法,这将产生冲突。如果您需要使用这两种方法,则必须小心地导入它们,责任在于您的代码:
class C
# Import A
include A
# Create an alias for A's version of the a method called `A_a`
alias_method :A_a, :a
# Import B
include B
end
C.new.a
# => :B
C.new.A_a
# => :A
现在,它们可以共存,而不是像两只愤怒的猫一样争斗。包含一个模块只会使该模块成为包含该模块的类的超类 因此,
include B
使B
成为C
的超类,而C
的前一个超类(即Object
)成为B
的超类。然后,include A
使A
成为C
的超类,而C
的前一个超类(即B
)成为A
的超类
因此,
A#A
只是覆盖B#A
。这没什么特别的。这只是无聊的旧类继承和方法重写。直接回答您的问题:这最终是使用gems的开发人员的责任。gems的作者应该注意恰当地命名他们的方法,但是他们能够(或者应该)做的任何事情都不会避免碰撞的可能性
Ruby的这一功能非常强大,但一如既往,强大的功能会带来巨大的灾难可能性。这与Rails无关,由Ruby语言处理。在这种情况下,
include A
覆盖了module B
中的A
函数,因为它是最后包含的。根据我的经验,“在现实世界中,一个gem中定义的方法名称很有可能与另一个gem的方法名称发生冲突”,但事实并非如此。那些依赖于include
导入的宝石通常会使它们的足迹非常小。