Using modules as namespaces to override built-in classes in Ruby
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:
- Always name your filenames lower case (
date.rb
notDate.rb
) - Put your files in a specific directory inside your library (
lib
is a good candidate) - 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
精彩评论