module X
end
module Y
end
module Z
#TODO include X replacement of including Y
#TODO include Y replacement of including X
end
有没有办法解决ruby不包含uninclude关键字的事实?
答案 0 :(得分:7)
如果您真的需要这种功能,可以使用refinements。
来完成class Foo
end
module X
def x
puts 'x'
end
end
module Y
end
module R
refine Foo do
include X
include Y
end
end
# In a separate file or class
using R
# Foo now includes X and Y
Foo.new.x
# In a different file or class
# Foo no longer includes X and Y
Foo.new.x # NoMethodError
答案 1 :(得分:1)
我对此并不满意,但如果两个模块包含相同的方法名称,它确实有效。
文件c.rb
module A
def me
puts "I am C"
end
def whosit?
puts "It's me, Becky"
end
end
文件d.rb
module A
def me
puts "I am D"
end
end
然后
class X
load('c.rb')
include A
end
x = X.new
x.me # => I am C
x.whosit? # => It's me, Becky
load('d.rb')
x.me # => I am D
x.whosit? # => It's me, Becky !! Unwanted !!
load('c.rb')
x.me # => I am C
load()
只是打开模块A并更改和/或添加代码;任何不接触的东西仍然存在。 load()
并不是真正的光明。我认为它基本上是eval()
并且如果它多次加载同一个文件可能会更少。
要使用此功能,请不要require
c.rb或d.rb。
编辑:在之前的编辑中,我添加了关于require_relative
的观察。经过反思,我发现这既不重要也不有趣,所以不用它的头。
答案 2 :(得分:1)
真正的答案是,在Ruby中,无论是1.x还是2.x,都有没有办法来包含一个模块。但我知道有人在某处编写了Ruby扩展,允许不包含模块。
编辑:好的,实际上,OP是What is the opposite of Ruby's include?的副本,因此根据@eliah和banister的答案,相关的库是https://github.com/yrashk/rbmodexcl和{{ 3}}
答案 3 :(得分:0)
如果您要创建一个可以动态选择是否包含模块的类,则可以通过在初始化期间将模块包含在singleton类中来实现。
这不会像在一个对象的单例类中“取消包含”该模块,而同时又将其包含在该类本身中一样(uninclude
对我来说就是这种想法),但可能如果可以为您带来一些想法,则将上述优化解决方案的某些功能(具有相同问题)与其他模式进行匹配。
module A
def hi; :hi; end
end
class Foo
def initialize(include_a = true)
singleton_class.include(A) if include_a
end
end
Foo.new.hi
# => :hi
Foo.new(false).hi
# NoMethodError: undefined method `hi' for #<Foo:0x00007fe19a973f00>
理解这是一个古老的问题,但是如果您正在寻找uninclude
功能,那么就值得考虑您到底想使用什么功能了-就像“动态包含”一样?