Question

I'm writing a Ruby gem with lots of nested classes and such. I'd like to keep a huge list of require statements out of my main Ruby file in the /lib directory, so instead I used the following:

Dir[ File.join( File.dirname(__FILE__), "**", "*.rb" ) ].each {|f| require f}

which totally worked fine until this morning when I added a new file (helper module) and now the library is acting like that file isn't loaded, even though it is. I checked with

puts "loaded" if defined?(RealtimeArgHelpers)

I also duplicated the require statement to check to see if my new file is getting returned

Dir[ File.join( File.dirname(__FILE__), "**", "*.rb" ) ].each {|f| puts f}

and it is. I have to manually require this one file. Out of nowhere. I have 101 other files currently being gathered by this statement and everything works perfectly fine. But not this one file. I don't have any name conflicts besides

/path/arg_helpers.rb
/path/realtime/agents.rb
/path/realtime/queues.rb
/path/realtime.rb
/path/realtime_arg_helpers.rb

which still shouldn't be a 'conflict.' I'm completely baffled by the seemingly random behavior, unless I'm doing something illegal in the language. I tried renaming the module, renaming the file, no dice. Why is this one file not getting loaded?

Was it helpful?

Solution

The problem comes from the way require works in Ruby. Whenever a file is required (let's only consider the case of a .rb source file to keep it simple), Ruby parses the file and immediately executes the instructions that are not in methods. So if you use classes that are defined in files yet to be loaded, Ruby won't find them.

I don't really know if there is a recommended way used by the gem authors to deal with that, but coming from a C/C++ background I tend to favour explicitly requiring the dependencies in each source file, rather than trying to maintain a giant sorted list in the main.rb (or equivalent).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top