Ruby 在相互依赖的模块中混合?
模块Ruby 在相互依赖的模块中混合?,ruby,Ruby,模块A依赖模块B,而类C依赖模块A和B。如果我将A和B包含在C中,这是可行的,但我不喜欢A依赖于另一个模块的事实,该模块必须与之混合才能工作 在这种情况下,混合模块的“正确”方式是什么?A是否应该混入B本身?如果C也直接使用B怎么办 module B def g 12 end end module A def f 2 * g end end class C include A, B def h 3 * f end end 您可以覆盖包含
A
依赖模块B
,而类C
依赖模块A
和B
。如果我将A
和B
包含在C
中,这是可行的,但我不喜欢A
依赖于另一个模块的事实,该模块必须与之混合才能工作
在这种情况下,混合模块的“正确”方式是什么?A
是否应该混入B
本身?如果C
也直接使用B
怎么办
module B
def g
12
end
end
module A
def f
2 * g
end
end
class C
include A, B
def h
3 * f
end
end
您可以覆盖包含的
模块
module A
def self.included(base)
base.class_eval do
include B
end
end
end
完成此操作后,B将包含在A之后
模块A有一个依赖于模块B.[…]中的功能的方法。在这种情况下,混合模块的“正确”方式是什么?A应该在B中混合吗?如果C也直接使用B呢
module B
def g
12
end
end
module A
def f
2 * g
end
end
class C
include A, B
def h
3 * f
end
end
你别无选择。应根据A、B和C之间的关系选择每一个
第一个是声明一个模块D
,该模块将定义a
和B
之间的共享功能。通过这种方式,您可以轻松地将D
与A
和B
混合使用,而不用担心太多:
module D; ...; end
module A; include D; ...; end
module B; include D; ...; end
我能想到的另一个方法是将A
和B
转换为类,以便使用继承。当有两个具有强依赖关系的类时,继承是好的。如果A
所使用的功能足够强大,您一定要选择此功能:
class B; ...; end
class A < B; ...; end
class C < A; ...; end
B类。。。;结束
A类
因为在您的情况下,没有同名的重写方法,所以无论您以何种方式混合混合混合,实例方法都将按预期协同工作。您只需确保他们真正融入:
[ A, B ].all? { |m| C.kind_of? m } # must be true
因此,在你的情况下,你是否这样做并不重要
class C; include A, B; end
还是这个
class C; include B, A; end
module B; include A end
class C; include B end
module A; include B end
class C; include A end
还是这个
class C; include B, A; end
module B; include A end
class C; include B end
module A; include B end
class C; include A end
还是这个
class C; include B, A; end
module B; include A end
class C; include B end
module A; include B end
class C; include A end
提醒您的一个警告是,这不起作用:
class C; include A; end # including the module A first
module A; include B end # and trying to remix it after
c = C.new # does not work
c.h # raises NoMethodError
# Modules have to have finished mixing when they are included.
就这些 如果A依赖于B,并且您的模块只定义实例方法,那么只在A中包含B没有什么错。如果您需要类方法,您可能需要考虑< /P>
重复编写
include
没有什么错。如果A
和C
都依赖于B
,那么在A
和C
中都包含B
module B
def g; 12 end
def i; 7 end
end
module A
include B
def f; 2 * g end
end
class C
include A, B
def h; 3 * f * i end
end
如果C
不依赖B
,则仅在A
中包含B
module B
def g; 12 end
end
module A
include B
def f; 2 * g end
end
class C
include A
def h; 3 * f end
end
你使用的是什么版本的Ruby?我似乎不明白你使用的
import
关键字。@BorisStitnicky,对不起。我的意思是包括。太多Python;)这是一个很好的解决方案,但请注意,如果a和B都实现了同一方法的版本,则加载顺序决定了方法的版本在对象上的结束时间!为什么不干脆base.include B
?