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 关键字的事实?
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 关键字的事实?
如果你真的需要这种功能,你可以通过使用细化来实现。
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
真正的答案是,在 Ruby 中,无论是 1.x 还是 2.x,一旦包含一个模块,就无法取消包含。但我知道有人在某处编写了允许不包含模块的 Ruby 扩展。
编辑:好的,实际上,OP 是 Ruby 包含的对立面的副本?,所以根据@eliah和banister的回答,有问题的库是https://github.com/yrashk/rbmodexcl和https://github.com/banister/mixology19
我对此不太满意,但如果两个模块包含相同的方法名称,它确实有效。
文件 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
. 回想起来,我发现它既不相关也不有趣,所以不以为然。
如果您想创建一个可以动态选择是否包含模块的类,您可以通过在初始化期间将模块包含在单例类中来实现。
这不会让你得到与在一个对象的单例类中“取消包含”模块相同的东西,同时保持包含在类本身中(这是我想到的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
功能,那么值得真正考虑一下您到底想用它做什么 - 像“动态包含”这样的东西就足够了吗?