ruby - 在 Ruby 的模块中包含模块时如何解决 namespace 冲突?

标签 ruby namespaces module include

这是我的代码:

module A
  def foo
    puts "A"
  end
end

module B
  include A
  def bar
    foo
  end
end

class MyClass
  include B
  def foo
    puts "X"
  end
  def self.test
    puts bar
  end
end

当我调用“C.test”时,我得到的是“X”而不是“A”(这是我想要的),因为 foo 的本地定义已经覆盖了 A 中的定义。我无法更改任何一个 foo 的签名.我只能主要编辑自己的类(class);我可以编辑模块 A 和 B,但许多现有代码都在使用它们,而且它们确实如此(例如,无需将 foo 更改为 A.foo)。我正在考虑做

class MyClass
  module MyModules
    include B
  end
  ....
    MyModules.bar
  ....
end

但这行不通。

在执行 include B 时如何“本地化”命名空间?

最佳答案

据我了解,您想覆盖 MyClass 中的 A#foo(B#bar 也使用它)。但是,您只想在 MyClass 中覆盖它,而不是在 B mixin 中覆盖它。

这里要理解的是,当 AB 混入的代码运行时,它们将成为 MyClass 实例。因此,不可能在不影响混入的情况下覆盖 MyClass 的实例方法。就好像 mixins 的方法被扔进了一个桶(MyClass 实例),然后运行。它们没有单独的作用域。因此,简单的回答是:不,你做不到。

虽然可能有几种可能的解决方案,其中许多都是 smell like pasta .遇到这样的问题可能表明整体设计决策需要进行一些重构。

复习模块的基础知识:

module Numbered
  DEFAULT = "1234-AWESOME"
  def serial_number
    DEFAULT
  end
  def self.awesome?
    true
  end
end

Numbered.awesome? # => true
Numbered.serial_number # whoops! NoMethodError.

o = Object.new
o.extend(Numbered)
o.serial_number #=> "1234-AWESOME"

Numbered.extend(Numbered)
Numbered.serial_number # => "1234-AWESOME"

class Dog
  extend Numbered
end

Dog.serial_number # => "1234-AWESOME"
Dog::DEFAULT # => "1234-AWESOME"
fido = Dog.new
fido.serial_number # NoMethodError!

这是因为该方法是作为类方法添加的。 include 来拯救:

class Fish
  include Numbered

  def serial_number
    super + '-FSH'
  end
end

cod = Fish.new
cod.serial_number # => "1234-AWESOME-FSH"

因此,include 将所有方法堆放在一个公共(public)实例中,但我们仍然可以使用 super 调用我们覆盖的包含方法。如果您在意大利面方面寻求解决方案,您可以在 bar 方法中使用 super,有条件地调用您覆盖的方法。

此外,根据具体情况,您可以设置一个新模块并使用包含您需要访问的方法的模块扩展它,就像您添加的答案中那样。

关于ruby - 在 Ruby 的模块中包含模块时如何解决 namespace 冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6704573/

相关文章:

ruby-on-rails - 使用 thin 在 Rails 3 应用程序中指定环境

ruby - 是否可以在 ruby​​ 类中调用重写的 to_s ?

c++ - C++中的 namespace 搜索

c++ - 如何调用不同命名空间中的函数?

javascript - setTimeout 如何查看模块内的私有(private)函数?

ruby - 是否有一个 Ruby Regex.match 版本可以响应字符串中匹配的顺序?

ruby - 如何只允许访问某些特定的 ruby​​ 类?

c++ - 使用 python 正则表达式从 C++ 源中提取命名空间

Python - Pymediainfo模块[错误126]找不到指定的模块

python - 使用 Python 的资源 (resx)