Ruby 在其他模块中包含一个模块
如何将模块B包含在A中,以便已经包含模块A的类也可以从模块B中获取方法?您应该在类C之前将B包含在A中;包括:;结束Ruby 在其他模块中包含一个模块,ruby,Ruby,如何将模块B包含在A中,以便已经包含模块A的类也可以从模块B中获取方法?您应该在类C之前将B包含在A中;包括:;结束 module A; def a; end; end module B; def b; end; end class C; include A; end module A; include B; end class D; include A; end C.new.b # undefined method error D.new.b # nil C.ancestors # [
module A; def a; end; end
module B; def b; end; end
class C; include A; end
module A; include B; end
class D; include A; end
C.new.b # undefined method error
D.new.b # nil
C.ancestors # [C, A, Object...]
D.ancestors # [D, A, B, Object...]
编辑
module A; def a; end; end
module B; def b; end; end
module A; include B; end
class C; include A; end
class D; include A; end
p C.new.b # nil
p D.new.b # nil
p C.ancestors # [C, A, B, Object, Kernel, BasicObject]
p D.ancestors # [D, A, B, Object, Kernel, BasicObject]
你不能
当您将混入M
到类C
中时,Ruby将创建一个新类⟦M′⟧
其方法表指向mixinM
的方法表,其超类是C
的超类,然后使该类成为C
的新超类。对于混合到M
中的每个mixin,都会重复此操作
请注意,当您将M
混合到C
中时,此算法只运行一次。稍后获得包含d的模块将不会被考虑。如前所述,Ruby不是这样工作的-当一个类包含一个模块时,它不会维护对该模块实例的任何引用,因此如果该模块包含其他模块,则已经包含的类将不知道该更改
您可以通过将包含模块的类存储在模块本身中来解决此问题,这样您就可以在模块包含另一个模块时更新这些类,例如:
module A; def a; end; end
module B; def b; end; end
class C; include A; end
module A; include B; end
class D; include A; end
C.send(:include, A)
p C.new.b # nil
p D.new.b # nil
p C.ancestors # [C, A, Object...]
p D.ancestors # [D, A, B, Object...]
模块A
classI无法更改类包含这些模块的顺序。我正在尝试扩展RailsActionDispatch::Routing::UrlFor
模块,该模块已经包含在一些Rails类中。这不是ActiveSupport::Concern
构建的目的吗?谢谢,但我的想法是,我想将我的模块包含在ActionDispatch::Routing::UrlFor
中,这样所有包含它的Rails类都会自动获得这些新方法。我不想迭代包含此模块的每个Rails类。如果我有一个所有这些类的列表,我可以简单地将我的模块直接包含到它们中。最终,你想在这里实现什么?你能用一个具体的例子来说明你的用例吗?也许你的问题可以用不同的方法解决。我想在ActionDispatch::Routing::UrlFor
Rails模块中包含我的模块,这样所有包含它的Rails类都会自动拥有我的新方法。我以不同的方式解决了这个问题,但很惊讶它不能以这种方式工作。
module A
class<<self
attr_accessor :observers
end
self.observers = []
def a
"#{self} successfully called a"
end
def self.included(base)
self.observers << base unless self.observers.include?(base)
end
def self.include(mod)
observers.each {|o| o.send(:include,mod) }
super
end
end
module B
def b
"#{self} successfully called b"
end
end
class C
include A
end
module A
include B
end
class D
include A
end
module E
def e
"#{self} successfully called e"
end
end
module A
include E
end
puts C.new.b
puts D.new.b
puts C.new.e
puts D.new.e