使用模块作为命名空间来覆盖Ruby中的内置类

时间:2010-09-26 00:00:44

标签: ruby module

我有一个Date类,我想用它来覆盖Ruby的Date类。但是,每当我在其他文件中执行require 'Date'时,它都包含Ruby的Date类,而不是我自己的类。

我认为将它放在模块中会很好用,所以我在Date.rb文件中这样做了:

module myModule
  class Date
  #...
  end
end

但是,我仍然无法弄清楚如何使我的其他类包括THIS Date类而不是内置类。我怎样才能做到这一点?

所有帮助都表示赞赏,并提前致谢!

3 个答案:

答案 0 :(得分:1)

require 'path/to/Date.rb'

class MyClass
    include MyModule::Date
end

答案 1 :(得分:1)

亚当,

您最好的选择就是遵循一些惯例:

  1. 始终将文件名命名为小写(date.rb而不是Date.rb
  2. 将您的文件放在库中的特定目录中(lib是一个很好的候选者)
  3. 不要将文件命名为与Ruby类中构建的文件相同(称为my_date.rb或其他内容),或者如果类/模块在模块内部是名称间隔的,则将其放在模块的文件夹中名称(lib/my_module/date.rb)。
  4. 这样可以消除您尝试加载的文件中的任何歧义。如果您绝对必须将其命名为date.rb,请通过执行以下操作加载完整路径:File.join(File.dirname(__FILE__), "date.rb")

    出于调试目的,您可以查看以下特殊变量,以查看正在加载的内容而不是文件:

    • $:将显示加载路径(即它查找的每个目录以查找要求的文件。您将注意到当前目录(.)是最后一个。这就是为什么您的文件不是' t loaded - 它首先在系统路径中查找。你可以随时通过$:.unshift(File.dirname(__FILE__))将当前目录移动到加载路径的前面作为解决方案,但是在尝试之前我会尝试上述方法之一此
    • $"显示到目前为止当前环境中所需的每个文件。

答案 2 :(得分:0)

首先,您需要正确的文件。通常,当您执行require 'date'并且基于$ LOAD_PATH解析为文件时,会发生正确的事情。将date.rb放在目录中可以更加具体,因此您可以require 'my_module/date'或仅使用./date

之类的相对路径

然后,您可以在引用此类时指定模块层次结构:

::MyModule::Date

或者您可以将其包含在您希望将Date调用此标准的地方而不指定:

class Event
  include MyModule
  def initialize
    @date = Date.today # refers to MyModule::Date
  end
end