开发者

Using modules as namespaces to override built-in classes in Ruby

开发者 https://www.devze.com 2023-01-17 19:56 出处:网络
I have a 开发者_运维知识库Date class which I would like to use to overwrite Ruby\'s Date class. However, whenever I do a require \'Date\' in my other files, it includes Ruby\'s Date class and not my o

I have a 开发者_运维知识库Date class which I would like to use to overwrite Ruby's Date class. However, whenever I do a require 'Date' in my other files, it includes Ruby's Date class and not my own.

I thought that putting it in a module would work well, so I did so within the Date.rb file:

module myModule
  class Date
  #...
  end
end

However I still can't figure out how to make my other classes include THIS Date class and not the built-in class. How can I achieve this?

All help is appreciated and thanks in advance!


Adam,

Your best bet is to simply follow some conventions:

  1. Always name your filenames lower case (date.rb not Date.rb)
  2. Put your files in a specific directory inside your library (lib is a good candidate)
  3. Don't name your files the same thing as built in Ruby classes (call it my_date.rb or something) or if your class/module is name-spaced inside a module, put it in a folder of the module name (lib/my_module/date.rb).

This removes any ambiguity in which file you are trying to load. If you absolutely must keep it named date.rb, then load it with the full path by doing something like: File.join(File.dirname(__FILE__), "date.rb").

For debugging purposes you can look at the following special variables to see what's being loaded instead of your file:

  • $: will show the load path (i.e. every directory it looks in to find files to require. You will note that the current directory (.) is last. This is why your file isn't loaded -- it looks in the system path first. You can always move your current directory to the front of the load path as a solution by doing $:.unshift(File.dirname(__FILE__)), but I'd try one of the above approaches before resorting to this
  • $" shows every file that has been required into your current environment so far.


require 'path/to/Date.rb'

class MyClass
    include MyModule::Date
end


First, you need to require the correct file. Often the right thing happens when you do require 'date' and it's resolved to a file based on your $LOAD_PATH. You can be more specific by putting your date.rb in a directory so you can require 'my_module/date' or just use a relative path like ./date

You can then specify the module hierarchy when referring to this class:

::MyModule::Date

Or you can include it wherever you prefer to call this Date over the standard one without specifying:

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

精彩评论

暂无评论...
验证码 换一张
取 消