Несоответствующее поведение «LoadError» с пространством имен / автозагрузкой «lib»

Мы только что создали новый файл в 'lib', который вызвал серию головных болей, связанных с ошибками загрузки.

/lib/response_set.rb:

module MyCompany
  class ResponseSet < Array
    ...
  end
end

/ spec / lib / response_set_spec.rb

require 'spec_helper'

describe MyCompany::ResponseSet do
  describe "..." do
    ...
  end
end

Запуск этой спецификации в Rspec дает нам следующую ошибку, когда доходит до первого «описания»:

/Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:492:in `load_missing_constant': Expected /Users/my_stuff/projects/my_project/lib/response_set.rb to define ResponseSet (LoadError)
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/backward_compatibility.rb:20:in `const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-expectations-2.5.0/lib/rspec/expectations/backward_compatibility.rb:6:in `const_missing'
    from /Users/my_stuff/projects/my_project/spec/lib/response_set_spec.rb:4:in `<top (required)>'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `load'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `block in load_spec_files'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `map'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:386:in `load_spec_files'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/command_line.rb:18:in `run'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:55:in `run_in_process'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:46:in `run'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/rspec-core-2.5.1/lib/rspec/core/runner.rb:10:in `block in autorun'

ОДНАКО! Мы долгое время использовали множество других файлов с идентичной структурой. Например, вот еще один файл, который отлично работает с момента его создания:

/lib/smart_set.rb

module MyCompany
  class SmartSet < Array
    ...
  end
end

И /spec/lib/smart_set_spec.rb

require 'spec_helper'

describe MyCompany::SmartSet do
  describe "..." do
    ...
  end
end

Этот файл имеет идентичную структуру, но не вызывает проблем.

ResponseSet (проблемный класс) явно имеет проблемы с загрузкой без видимой причины. В консоли rails, когда я в первый раз пытаюсь создать его, я получаю сообщение об ошибке, но потом я могу создать его:

Loading development environment (Rails 3.0.4)
ruby-1.9.2-p136 :001 > rs = MyCompany::ResponseSet.new
LoadError: Expected /Users/my_stuff/projects/my_project/lib/response_set.rb to define ResponseSet
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:492:in `load_missing_constant'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:503:in `load_missing_constant'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:183:in `block in const_missing'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `each'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:181:in `const_missing'
    from (irb):1
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands/console.rb:44:in `start'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands/console.rb:8:in `start'
    from /Users/my_stuff/.rvm/gems/ruby-1.9.2-p136@my_project/gems/railties-3.0.4/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
ruby-1.9.2-p136 :002 > rs = MyCompany::ResponseSet.new
 => [] 

Кроме того, добавление

require 'response_set'

в начало response_set_spec.rb позволяет запускать эти тесты. Но для smart_set_spec.rb в этом нет необходимости.

В application.rb имеется следующее:

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/**/"]

Теперь я понимаю, что у Rails есть какое-то мнение о том, как файловая структура должна соответствовать структуре пространства имен для этих типов вещи, и с этой целью мы реструктурировали наши модули и файлы. Похоже, проблема была устранена (хотя мы некоторое время наблюдали некоторые другие странные ошибки загрузки, когда запускали полный набор тестов - они таинственным образом исчезли). Тем не менее, все здесь сбиты с толку и немало раздражены тем, что Rails настолько непоследователен, и мы хотели бы знать, почему. Как видите, есть два файла, которые идентичны по пространству имен и структуре файлов, но обрабатываются совершенно по-разному. Фактически у нас есть около дюжины других файлов на верхнем уровне lib с аналогичным пространством имен, которые никогда не вызывали никаких проблем. Кто-нибудь может объяснить, что, черт возьми, здесь происходит?

24
задан Nick M 16 August 2011 в 17:01
поделиться