ruby: wie zu verlangen, richtig (zur Vermeidung von zyklischen Abhängigkeiten)

heute war ich vor einem seltsamen problem:
habe einen "missing method" - Fehler auf einem Modul, aber die Methode war da, und die Datei, wo das Modul definiert wurde, war erforderlich. Nach einigem suchen fand ich eine zirkuläre Abhängigkeit, wo 2 Dateien erforderlich, jedes andere, und jetzt nehme ich an ruby leise bricht kreisförmigen erfordert.


Bearbeiten Beginnen: Beispiel

Datei 'ein.rb':

require './b.rb'

module A
    def self.do_something
        puts 'doing..'
    end
end

Datei 'b.rb':

require './a.rb'

module B
    def self.calling
        ::A.do_something
    end
end

B.calling

Ausführung b.rb gibt b.rb:5:in 'calling': uninitialized constant A (NameError). Die verlangt haben, es gibt für beide Dateien, wie Sie ausgeführt werden sollen, auf Ihrer eigenen von der Kommandozeile aus (i entfallen, die code, es kurz zu halten).
So B. die Berufung hat, dort zu sein. Eine mögliche Lösung ist, wickeln Sie das erfordert in if __FILE__ == $0, aber das scheint nicht der richtige Weg zu gehen.

Edit Ende


zur Vermeidung dieser schwer zu findende Fehler (wäre es nicht schöner, wenn das erforderlich ist, wirf eine Ausnahme, übrigens?), gibt es einige Richtlinien/Regeln bei der Strukturierung eines Projektes und, wo erforderlich, was? Zum Beispiel, wenn ich

module MainModule
  module SubModule
    module SubSubModule
    end
  end
end

wo sollte ich muss die Submodule? alle in der Haupt-oder nur den sub in der Haupt-und subsub in der sub?

jede Hilfe wäre sehr nett.

Zusammenfassung

Einer Erklärung, warum dies geschieht, ist diskutiert in forforfs Antwort und Kommentare.

Bisher beste Praxis (wie hingewiesen oder angedeutet durch gelegen) scheint Folgendes zu sein (bitte korrigiert mich wenn ich falsch Liege):

  1. jedem Modul oder die Klasse in die top-namespace in eine Datei benannt nach dem Modul/Klasse. in meinem Beispiel wären dies 1 Datei mit dem Namen 'main_module.rb.'
    wenn es teilmodule oder-Unterklassen, erstellen Sie ein Verzeichnis, benannt nach dem Modul/Klasse (in meinem Beispiel ein Verzeichnis 'main_module', und legen Sie die Dateien für die Unterklassen/teilmodule dort (im Beispiel 1-Datei mit dem Namen 'sub_module.rb'). wiederholen Sie dies für jede Ebene des namespace.
  2. benötigen-Schritt für Schritt (im Beispiel die MainModule erfordern würde, die SubModule, und die Submodule erfordern würde, die SubSubModule)
  3. separates "running" - code von 'Definition' code. in der Ausführung von code erfordern, sobald Sie Ihre top-level-Modul/Klasse, so wegen 2. alle Ihre-Bibliothek-Funktionen sollten nun verfügbar sein, und Sie können jeden definierten Methoden.

Dank an alle, die geantwortet/kommentiert, es hat mir sehr geholfen!

  • Dein Beispiel produziert nicht ein Fehler; es funktioniert für mich. Sieht aus wie Sie haben vereinfacht, Ihr code zu dem Punkt, wo es nicht zu zeigen, Ihr problem. Meine Antwort auf Ihre Frage über die Reihenfolge des Ladens gewesen wäre deinem Beispiel-code! 🙂
  • das ist merkwürdig, ich habe tatsächlich lief der code und es HAT zu produzieren, dass errror Meldung. ich bin mit ruby 1.9.2p180, was verwenden Sie?
  • 1.8.7 und 1.9.3.
  • gut, versuchte ich es mit ruby 1.8.7p330, die gibt mir auch den gleichen Fehler. vielleicht haben Sie nicht copy/paste richtig.
InformationsquelleAutor user573335 | 2011-11-08
Schreibe einen Kommentar