2013-12-08 15 views
5

Ich habe einen sehr merkwürdigen Fehler, den ich mir nicht verkneifen kann.Klasse ist erforderlich, aber kein Zugriff möglich

Grundsätzlich habe ich diese Klasse in meinem lib Ordner:

# lib/api/amazon.rb 
module API 
    class Amazon 
    ... 
    end 
end 

Wenn ich es will irgendwo verwenden, ich require es:

require 'api/amazon' 
API::Amazon.do_stuff 

Dies funktioniert zunächst aber nach einer Weile bricht und wirft NameError: uninitialized constant API::Amazon. Wenn ich debuggen und require die Datei erneut versuchen, wenn der Fehler ausgelöst wird, gibt es false zurück, die angibt, dass die Datei bereits geladen wurde. Ich kann es auch in $" (diese Liste der geladenen Dateien) sehen. Warum kann ich dann nicht auf API::Amazon zugreifen?

Hinweis: Ich habe "API" als Akronym auf ActiveSupport::Inflector, weshalb ich muss nicht verwenden "Api": gleiche

Ich versuchte ::API::Amazon.do_stuff Auch:

# config/initializers/inflections.rb 
ActiveSupport::Inflector.inflections do |inflect| 
    inflect.acronym 'API' 
end 

EDIT Ergebnis.

+0

Es sieht so aus, als würde 'ActiveSupport' von Zeit zu Zeit einige Aufräumarbeiten an seinen verschachtelten Klassen durchführen und dabei automatisch erstellte entfernen. Dies kann erforderlich sein, wenn jemand eine dynamische Klassenerweiterung mit 'class_eval'-ähnlichen Methoden verwendet. – mudasobwa

+0

Weiß nicht genau, was Sie damit meinen, @mudasobwa.Ich benutze kein dynamisches 'class_eval' Zeug, es ist eine reguläre Klasse ohne jegliche dynamische oder metaprogrammierende Magie. –

+0

Sie definieren eine Klasse unter bereits vorhandenem (und eingefrorenem) [ihrer Politik] (http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html)) Modul; Sagen wir, du hast "ActiveSupport :: Inflector" gefunden. 'ActiveSupport', einmal geladen, kann eine solche Bereinigung für ** es ** verschachtelte Klassen durchführen. – mudasobwa

Antwort

1

Ich schreibe einen Code, der darauf abzielt, das gleiche Ergebnis zu erhalten wie Ihres, vielleicht kann es einen Hinweis geben.

trytemp.rb:

module API 
    class Amazon 
    def hello 
     puts "API::Amazon initially works well" 
     $stdout.flush 
    end 
    end 
end 

s = API::Amazon.new 
s.hello 

p API.constants 
API = Module.new 
p API.constants # Here you can see constant Amazon disappers from module API 
s = API::Amazon.new 
s.hello 

Es anfangs gut funktioniert, dann gleichen Fehler "nicht initialisierte Konstante API :: Amazon (Nameerror)":

$ ruby trytemp.rb 
API::Amazon initially works well 
[:Amazon] 
trytemp.rb:15: warning: already initialized constant API 
[] 
trytemp.rb:19:in `<main>': uninitialized constant API::Amazon (NameError) 
+0

Sie haben einen Fehler in Ihrem Code (korrigieren Sie mich, wenn ich falsch liege). Nur die Klasse kann nicht Modul (Module.new) initialisiert werden. –

+0

@maro30. Sie haben wirklich Unrecht. Sie sind verwirrt mit Modul und einer Instanz von Modul. Zum Beispiel ist API eine Instanz von Module. Mit anderen Worten, Modul ist eine Klasse und API ist ein Modul. – uncutstone

+0

ok woher kommt das "Modul" mit der hauptschrift 'M'? Wenn 'API' eine Instanz davon ist, dann soll' Module' eine Klasse sein. Nur versuchen, Ihren Code zu verstehen ... –

0

EDIT:

Ich habe zwar die Antwort gefunden, aber derselbe Fehler ist gerade wieder aufgetreten ... :(

ENDE EDIT

Es scheint, dass ich die Antwort gefunden habe, mit Hilfe von @uncutstone.

Stellt sich heraus, ich hatte nicht nur den API Namespace für API::Amazon verwendet, sondern auch für einige Controller, etwa so:

# app/controllers/api/v1/accounts_controller.rb 
class API::V1::AccountsController < APIController 
    ... 
end 

Meine Theorie ist, dass einer dieser Controller automatisch zu einem bestimmten Zeitpunkt und wieder neu geladen wurde - initialisiert (und damit ausgeräumt) das API Modul/Namespace. So API::Amazon war danach nicht verfügbar, aber re require ing lib/api/amazon.rb half nicht, weil es bereits benötigt wurde und daher nicht erneut geladen wurde. ich die Controller geändert wie folgt aussehen:

# app/controllers/api/v1/accounts_controller.rb 
module API 
    class V1::AccountsController < APIController 
    ... 
    end 
end 

und jetzt scheint es zu funktionieren.

+0

Es scheint auch wie dies ist/war nur ein Problem in der Entwicklung, in der Produktion trat der Fehler nie auf. –

Verwandte Themen