iftheshoefritz
iftheshoefritz

Reputation: 6119

Reliable require of multiple files while respecting dependencies?

A required Ruby file isn't finding a constant in another file in the same location, I suspect because of the order Ruby receives the files from the filesystem when using Dir.each. Different behaviour occurs on different machines/OSes. Is there a filesystem independent approach to using require?

In a rails app with rspec we have a spec_helper that requires everything under spec/support:

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

In a module under that tree, Class A inherits from B, but on one machine (MacOS) a.rb is required before b.rb and dies because it can't find A. On another machine (Ubuntu) there is no problem. In fact I can't see a good reason why it should work on that machine.

#a.rb
puts "required A"
module MyModule
  class A < B
  end
end

#b.rb
puts "required B"
module MyModule
  class B
  end
end

When the specs run on the Mac, the Dir.each {require} causes the following output:

required A
/Users/me/myproject/spec/support/mymodule/a.rb:4:in `<module:MyModule>': uninitialized constant MyModule::B (NameError)

On the Ubuntu machine, we have

required B
required A

... no error. Since it's not alphabetic I guess that the Ruby on Ubuntu is getting the files on something other than filename, perhaps on timestamp or physical position on the disk. Both of these seem quite tenuous.

Upvotes: 1

Views: 211

Answers (3)

iftheshoefritz
iftheshoefritz

Reputation: 6119

The gem require_all appears to do what I want.

Upvotes: 0

BM5k
BM5k

Reputation: 1230

Explicitly require b from inside a:

#a.rb
require 'b'
puts "required A"
module MyModule
  class A < B
  end
end

This will guarantee that b is always required before a, regardless of operating system load order.

Upvotes: 1

A Fader Darkly
A Fader Darkly

Reputation: 3626

It's just an array, so you could just do this:

Dir[Rails.root.join("spec/support/**/*.rb")].sort.reverse.each { |f| require f }

Then ensure that dependencies are met in the correct order.

Upvotes: 0

Related Questions