Saturday, April 05, 2008

[Ruby] Madness with the 'require' command

I spent around 30 minutes trying to figure out why a particular Ruby file was being loaded twice, only to be struck in my face with this gotcha.

Basically, when you use require 'file' the method Ruby uses to determine whether the file has been loaded earlier is pretty stupid. It looks for the filename passed verbatim in it's internal data structure/hash/whatever. So, if you give require 'file' and require './file' the damn file will be loaded twice.

WTF?! Seriously!

Anyways, I thought this was undocumented behaviour but I found this in the RDoc entry for 'require' - should have looked there before.

Ruby tries to load the library named string, returning true if successful. If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $:. If the file has the extension ``.rb’’, it is loaded as a source file; if the extension is ``.so’’, ``.o’’, or ``.dll’’, or whatever the default shared library extension is on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding ``.rb’’, ``.so’’, and so on to the name. The name of the loaded feature is added to the array in $". A feature will not be loaded if it‘s name already appears in $". However, the file name is not converted to an absolute path, so that ``require ‘a’;require ’./a‘’’ will load a.rb twice.

No comments:

Post a Comment