Ruby 2.0如何在包含模块后从模块中取出模块?

时间:2021-03-29 23:17:03
module X
end

module Y
end

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

Is there a way to work around the fact that ruby contains no uninclude keyword??

有没有办法解决ruby不包含uninclude关键字的事实?

Ruby 2.0如何在包含模块后从模块中取出模块?

3 个解决方案

#1


6  

If you really need this kind of functionality, you could probably do it by using 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

#2


1  

The genuine answer is that in Ruby, be it 1.x or 2.x, there is no way to uninclude a module once included. But I know that someone, somewhere has written Ruby extension that allows unincluding modules.

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

EDIT: OK, actually, OP is the duplicate of What is the opposite of Ruby's include?, so according to its answer by @eliah and banister the libraries in question are https://github.com/yrashk/rbmodexcl and https://github.com/banister/mixology19

编辑:好的,实际上,OP是Ruby的包含的反义词的副本?所以根据@eliah和banister的回答,有问题的库是https://github.com/yrashk/rbmodexcl和https:/ /github.com/banister/mixology19

#3


1  

I'm not too happy with this, but it does work if both modules contain the same method names.

我对此并不满意,但如果两个模块包含相同的方法名称,它确实有效。

file c.rb

文件c.rb

module A
  def me
    puts "I am C"
  end
  def whosit?
    puts "It's me, Becky"
  end
end

file d.rb

文件d.rb

module A
  def me
    puts "I am D"
  end
end

Then

然后

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() is just opening module A and changing and/or adding code; anything there that it does not touch remains. load() is not real bright. I think it basically does an eval() and could care less if it loads the same file more than once.

load()只是打开模块A并更改和/或添加代码;那里没有触及的任何东西仍然存在。 load()不是很明亮。我认为它基本上是一个eval(),并且如果它多次加载同一个文件可能会更少。

To use this, do not also require c.rb or d.rb.

要使用它,不要求c.rb或d.rb.

Edit: In an earlier edit I added an observation about require_relative. On reflection, I see it was neither relevant nor interesting, so off with its head.

编辑:在之前的编辑中,我添加了一个关于require_relative的观察。经过反思,我发现它既不重要也不有趣,所以它的头部也是如此。

#1


6  

If you really need this kind of functionality, you could probably do it by using 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

#2


1  

The genuine answer is that in Ruby, be it 1.x or 2.x, there is no way to uninclude a module once included. But I know that someone, somewhere has written Ruby extension that allows unincluding modules.

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

EDIT: OK, actually, OP is the duplicate of What is the opposite of Ruby's include?, so according to its answer by @eliah and banister the libraries in question are https://github.com/yrashk/rbmodexcl and https://github.com/banister/mixology19

编辑:好的,实际上,OP是Ruby的包含的反义词的副本?所以根据@eliah和banister的回答,有问题的库是https://github.com/yrashk/rbmodexcl和https:/ /github.com/banister/mixology19

#3


1  

I'm not too happy with this, but it does work if both modules contain the same method names.

我对此并不满意,但如果两个模块包含相同的方法名称,它确实有效。

file c.rb

文件c.rb

module A
  def me
    puts "I am C"
  end
  def whosit?
    puts "It's me, Becky"
  end
end

file d.rb

文件d.rb

module A
  def me
    puts "I am D"
  end
end

Then

然后

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() is just opening module A and changing and/or adding code; anything there that it does not touch remains. load() is not real bright. I think it basically does an eval() and could care less if it loads the same file more than once.

load()只是打开模块A并更改和/或添加代码;那里没有触及的任何东西仍然存在。 load()不是很明亮。我认为它基本上是一个eval(),并且如果它多次加载同一个文件可能会更少。

To use this, do not also require c.rb or d.rb.

要使用它,不要求c.rb或d.rb.

Edit: In an earlier edit I added an observation about require_relative. On reflection, I see it was neither relevant nor interesting, so off with its head.

编辑:在之前的编辑中,我添加了一个关于require_relative的观察。经过反思,我发现它既不重要也不有趣,所以它的头部也是如此。