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