2013-10-19 172 views
10
module X 
end 

module Y 
end 

module Z 
    #TODO include X replacement of including Y 
    #TODO include Y replacement of including X 
end 

有没有办法解决这个事实,即红宝石不包含uninclude关键字?Ruby 2.0如何在包含模块后从模块中取出模块?

enter image description here

+0

的可能重复【什么是Ruby的包括相反?] (http://stackoverflow.com/questions/2088211/what-is-the-opposite-of-rubys-include) –

+0

@LoganSerman ruby​​ 2.0的回答我寻求 – zotherstupidguy

+0

*包括X包括Y *的替换手段? –

回答

5

如果你真的需要这种功能,你很可能使用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

我对此不太满意,但是如果两个模块都包含相同的方法名称,它就会工作。

文件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的观察。经过反思,我发现它既不相关也不感兴趣,因此它的头脑也是如此。

1

真正的答案是,在Ruby中,无论是1.x还是2.x,都有没有办法取消包含一个模块。但是我知道有人在某处写了Ruby扩展,允许unincluding模块。

编辑:好的,实际上,OP是What is the opposite of Ruby's include?重复的,所以要根据它的答案被@eliahbanister有问题的库https://github.com/yrashk/rbmodexclhttps://github.com/banister/mixology19

+0

鲍里斯它太老一样mixology - 期望问题&我不是C挑战,我登记davogones&cary答案,负载是智能解决方案,细化更清洁。如果细化为我工作,绝对会让世界知道它是需要的! – zotherstupidguy

+0

你是对的。我没有试过这些库。我认为Matz一开始并没有提供这种功能,这一定是有原因的。 –