Inkonsistent "LoadError" Verhalten mit 'lib' Namensräume/autoloading
Wir haben soeben eine neue Datei in 'lib', die hervorgebracht hat eine Reihe von Kopfschmerzen mit Last Fehler.
/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
Läuft diese Skillung in Rspec gibt uns der folgende Fehler, wenn es um den ersten 'beschreiben':
/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'
JEDOCH! Wir wurden mit vielen anderen Dateien, die für eine lange lange Zeit, die identische Struktur. Zum Beispiel, hier ist noch eins, dass hat wunderbar funktioniert, seit es erstellt wurde:
/lib/smart_set.rb
module MyCompany
class SmartSet < Array
...
end
end
Und /spec/lib/smart_set_spec.rb
require 'spec_helper'
describe MyCompany::SmartSet do
describe "..." do
...
end
end
Diese Datei hat die gleiche Struktur, verursacht aber keine Probleme.
ResponseSet ( die problem-Klasse ) hat offenbar be-Fragen für keinen erkennbaren Grund. In der rails-Konsole, das erste mal, dass ich versuchen, einen zu erstellen, bekomme ich eine Fehlermeldung, aber dann kann ich erstellen ein danach:
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
=> []
Auch das hinzufügen
require 'response_set'
oben response_set_spec.rb können die tests ausgeführt werden. Aber Nein, so etwas ist notwendig für smart_set_spec.rb.
Folgenden wird an Ort und Stelle in Anwendung.rb:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
Nun, ich verstehe, dass die Schienen irgendeine Art von Stellungnahme, wie die Datei-Struktur übereinstimmen sollten, namespace-Struktur für diese Art von Dingen, und wir haben umstrukturiert, unsere Module und Dateien auf dieses Ziel hin. Es SCHEINT wurde das Problem behoben (obwohl wir sahen einige andere seltsame Fehler beim laden für eine Weile, wenn wir liefen das komplette test-suite - diese haben mysteriöse Weise verschwunden). Dennoch, jeder hier ist verblüfft und nicht wenig verärgert, dass die Schienen ist so inkonsistent, und wir würden gerne wissen, warum. Wie Sie sehen können, gibt es zwei Dateien sind identisch, so weit wie Namensräume und Datei-Struktur, die betroffen sind, behandelt ganz anders. In der Tat haben wir über ein Dutzend andere Dateien in der obersten Ebene des 'lib' mit ähnlichen Verwendung von Namensräumen, die haben nie Probleme bereitet. Kann mir jemand erklären, was zum Teufel ist hier Los?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hatten wir ein ähnliches Problem, nach dem Graben, stellte sich heraus, dass der Fehler durch die änderungen in Rails 3.x und
autoload_paths
.Unserem Fall erschien nur in test (
RAILS_ENV=test
). Wenn Schienen, war das laden der Controller, es krabbelte über die Suche für jeden controller ein matching-Modell (aufgrund einer ActionController::Base.wrap_parameters in einem Initialisierer). Schließlich neigte sich dem Ende zu dem oben genannten Verfahren (load_missing_constant). Da unsere autoload_paths enthalten beide lib und lib/**, Schienen gezogen, in der alle Dateien aus allen Unterverzeichnissen unter lib. Leider, es scheint zu ignorieren das stillschweigend namespace beim laden von Unterverzeichnissen. Es erwartet foo/base.rb zu definierenBase
vs.Foo::Base
. Das scheint der Kern-Fehler:load_missing_constant
ruftsearch_for_file
gibt eine Datei, deren name mit (z.B., in meinem Beispiel, foo/base.rb zurückgegeben wurde, wie es abgestimmt base.rb).Es ist schwer zu sagen, ob dies ein Fehler in Schienen - in, dass es gegen die namespace-zu-Verzeichnis-Zuordnung übernommen Ruby - oder ein Missbrauch von autoload_paths.
Haben wir hart gearbeitet, um dies jetzt durch das entfernen
lib/**
von unsererautoload_paths
und hinzufügen der notwendigen erfordern Aussagen zur Anwendung.rb.Schaute ich in das Schienen-source und es gibt eine
Klausel in
load_missing_constant
Methode. Ich kann erraten, die alsrequire_or_load
aufgerufen wird, bevorraise
dies könnte ein Grund dafür sein, dass auf den zweiten Anruf in deinem Beispiel gibt es keine Fehler...Wäre es interessant zu sehen, ein minimal-Beispiel, wo zwei Dateien mit identischer Struktur Verhalten sich anders.
An deiner Stelle würde ich eine Kopie der Anwendung und halten würde das entfernen der Teile aus, während das inkonsistente Verhalten vorhanden ist, um zu sehen, die minimal inkonsistenten Beispiel.
P. S. ich vorgelegt haben, eine ähnliche Frage hier: http://www.ruby-forum.com/topic/2376956
ResponseSet
während es definiertMyCompany::ResponseSet
(dies ist, wie es bei mir aussieht, aber ich bin kein Fachmann). Die Inkonsistenz ist das, was den meisten Fremd. Seid Ihr sicher, dass Sie nicht die Vereinfachung des ursprünglichen Problems? VielleichtMyCompany::SmartSet
ist in/lib/my_company/smart_set.rb
und nicht nur/lib/smart_set.rb
? Ich legte eine bug-report auf GitHub zu einem ähnlichen Problem.War, wies in die richtige Richtung von Brendan, überprüfen Sie Ihre autoload_paths. Ich hatte einen ähnlichen Fehler und das war der Schuldige für mich in der Anwendung.rb :
Meine app war nicht glücklich, als ich begann, die Verwendung der Module für die Modelle zusammen mit sub-Verzeichnissen. Ich änderte meinen, um die autoload-nur die nicht-Modul-Verzeichnisse :
Habe ich litt unter dem selben problem mit Namespaces Klassen geladen falsch. Dies ist der Schlüssel, um es zu lösen (von Brendan Antwort):
Und ich habe es gelöst, indem Sie alle meine Namespaces, Klassen, benannt
Events::Something
, inapp/components/events/*
und erstellen Sie eine Dateiapp/components/events.rb
mit folgendem Inhalt:Und zwar ist dies ein wenig Anleitung, es funktioniert sowohl für Anwendungs -, Konsolen-und test-Modi.
Anderen Punkt Wert zu bemerken ist, dass, ob Sie haben den richtigen Pfad in den Ordner services.
Vom richtigen Weg, meine ich
Modulname/app/services/Modulname/your_service.rb
Habe ich versehentlich vergessen Modulname Ordner innerhalb von Diensten, und habe dieses seltsame Verhalten.