Ich habe zwei häufig verwendete Techniken zum Hinzufügen des Verzeichnisses der aktuell ausgeführten Datei zu $ LOAD_PATH (oder $ :) gesehen. Ich sehe die Vorteile, wenn Sie nicht mit einem Edelstein arbeiten. Einer scheint natürlich ausführlicher zu sein als der andere, aber gibt es einen Grund, mit einem über den anderen zu gehen?
Die erste, ausführliche Methode (könnte übertrieben sein):
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
und das unkompliziertere, schnellere und schmutzigere:
$:.unshift File.dirname(__FILE__)
Gibt es einen Grund, übereinander zu gehen?
File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}
__dir__
(ab Ruby 2.0) kann eine dieser Funktionen präziser gestaltet werden.Antworten:
Ich würde sagen, gehen Sie mit
$:.unshift File.dirname(__FILE__)
dem anderen über, einfach weil ich gesehen habe, dass es im Code viel häufiger verwendet wird als im$LOAD_PATH
einen, und es ist auch kürzer!quelle
Der Ruby-Ladepfad wird sehr häufig als $: geschrieben, aber nur weil er kurz ist, wird er nicht besser. Wenn Sie Klarheit der Klugheit vorziehen oder wenn die Kürze um ihrer selbst willen Sie jucken lässt, müssen Sie dies nicht tun, nur weil es alle anderen tun. Sag Hallo zu ...
... und verabschieden Sie sich von ...
quelle
Ich mag den "schnellen und schmutzigen" Weg nicht besonders. Jeder, der neu bei Ruby ist, wird darüber nachdenken, was
$:.
ist.Ich finde das offensichtlicher.
Oder wenn es mir wichtig ist, den vollen Weg zu haben ...
UPDATE 10.09.2009
In letzter Zeit habe ich Folgendes gemacht:
Ich habe es in einer ganzen Reihe verschiedener Ruby-Projekte gesehen, als ich GitHub durchsucht habe.
Scheint die Konvention zu sein?
quelle
bin
Datei hatten, die immer relativ zu Ihrer warcode
und immer nur von derbin
Datei ausgeführt wurde ... Bootstrap im Bin. Wenn Sie eine Bibliothek haben, booten Sie oben in Ihrem Bibliothekscode wie inlib/code.rb
, um Zugriff auf alles unter zu erhaltenlib/code/
. Hoffe, diese Wanderung hilft!__dir__
ein Pfad zum Verzeichnis der aktuellen Datei abgerufen werden kann.Wenn Sie
script/console
Ihr Rails-Projekt eingeben und eingeben$:
, erhalten Sie ein Array, das alle zum Laden von Ruby erforderlichen Verzeichnisse enthält. Das Mitnehmen von dieser kleinen Übung ist, dass$:
es sich um ein Array handelt. In diesem Fall können Sie Funktionen ausführen, z. B. andere Verzeichnisse mit derunshift
Methode oder dem<<
Operator voranstellen . Wie Sie in Ihrer Aussage angedeutet haben$:
und gleich$LOAD_PATH
sind.Der Nachteil, wie Sie bereits erwähnt haben, ist folgender: Wenn Sie das Verzeichnis bereits in Ihrem Startpfad haben, wiederholt es sich.
Beispiel:
Ich habe ein Plugin namens todo erstellt. Mein Verzeichnis ist wie folgt aufgebaut:
In die Datei init.rb habe ich folgenden Code eingegeben:
Beachten Sie, wie ich den Codeblock anweise, die Aktionen innerhalb des Blocks für die Zeichenfolgen "Modelle", "Controller" und "Modelle" auszuführen, wobei ich "Modelle" wiederhole. (FYI,
%w{ ... }
ist nur eine andere Möglichkeit, Ruby anzuweisen, eine Reihe von Zeichenfolgen zu halten). Wenn ich laufescript/console
, gebe ich Folgendes ein:Und ich tippe dies ein, damit es einfacher ist, den Inhalt der Zeichenfolge zu lesen. Die Ausgabe, die ich bekomme, ist:
Wie Sie sehen, ist dies zwar ein so einfaches Beispiel, das ich während der Verwendung eines Projekts erstellen könnte, an dem ich gerade arbeite. Wenn Sie jedoch nicht aufpassen, führt der schnelle und schmutzige Weg zu wiederholten Pfaden. Der längere Weg sucht nach wiederholten Pfaden und stellt sicher, dass sie nicht auftreten.
Wenn Sie ein erfahrener Rails-Programmierer sind, haben Sie wahrscheinlich eine sehr gute Vorstellung davon, was Sie tun, und machen wahrscheinlich nicht den Fehler, Pfade zu wiederholen. Wenn Sie ein Neuling sind, würde ich den längeren Weg gehen, bis Sie wirklich verstehen, was Sie tun.
quelle
load_paths
undload_once_paths.delete
sind veraltet. Würde geholfen werden, die Zeilen, die auf sie verweisen, wieActiveSupport::Dependencies.autoload_paths << path
ActiveSupport::Dependencies.autoload_once_paths.delete(path)
Am besten, ich bin auf das Hinzufügen eines Verzeichnisses über einen relativen Pfad gestoßen, wenn ich Rspec verwende. Ich finde es ausführlich genug, aber auch immer noch ein schöner Einzeiler.
quelle
Es gibt ein Juwel, mit dem Sie Ihren Ladepfad mit schönerem und saubererem Code einrichten können. Überprüfen Sie dies: https://github.com/nayyara-samuel/load-path .
Es hat auch eine gute Dokumentation
quelle
Ich weiß, dass diese Frage schon lange nicht mehr gestellt wurde, aber ich habe eine zusätzliche Antwort, die ich teilen möchte.
Ich habe mehrere Ruby-Anwendungen, die über mehrere Jahre von einem anderen Programmierer entwickelt wurden, und sie verwenden dieselben Klassen in den verschiedenen Anwendungen erneut, obwohl sie möglicherweise auf dieselbe Datenbank zugreifen. Da dies gegen die DRY-Regel verstößt, habe ich beschlossen, eine Klassenbibliothek zu erstellen, die von allen Ruby-Anwendungen gemeinsam genutzt wird. Ich hätte es in die Ruby-Hauptbibliothek stellen können, aber das würde benutzerdefinierten Code in der allgemeinen Codebasis verbergen, was ich nicht wollte.
Ich hatte ein Problem, bei dem ein Namenskonflikt zwischen einem bereits definierten Namen "profile.rb" und einer von mir verwendeten Klasse bestand. Dieser Konflikt war kein Problem, bis ich versuchte, die allgemeine Codebibliothek zu erstellen. Normalerweise durchsucht Ruby zuerst die Anwendungsspeicherorte und wechselt dann zu den Speicherorten $ LOAD_PATH.
Die application_controller.rb konnte die von mir erstellte Klasse nicht finden und hat einen Fehler in der ursprünglichen Definition ausgelöst, da es sich nicht um eine Klasse handelt. Da ich die Klassendefinition aus dem Abschnitt app / models der Anwendung entfernt habe, konnte Ruby sie dort nicht finden und suchte sie in den Ruby-Pfaden.
Daher habe ich die Variable $ LOAD_PATH so geändert, dass sie einen Pfad zu dem von mir verwendeten Bibliotheksverzeichnis enthält. Dies kann zur Initialisierungszeit in der Datei environment.rb erfolgen.
Selbst mit dem neuen Verzeichnis, das dem Suchpfad hinzugefügt wurde, gab Ruby einen Fehler aus, da die systemdefinierte Datei bevorzugt zuerst verwendet wurde. Der Suchpfad in der Variablen $ LOAD_PATH durchsucht vorzugsweise zuerst die Ruby-Pfade.
Daher musste ich die Suchreihenfolge ändern, damit Ruby die Klasse in meiner gemeinsamen Bibliothek fand, bevor sie die integrierten Bibliotheken durchsuchte.
Dieser Code hat es in der Datei environment.rb getan:
Ich glaube nicht, dass Sie eines der zuvor auf dieser Ebene angegebenen erweiterten Codierungskonstrukte verwenden können, aber es funktioniert einwandfrei, wenn Sie zur Initialisierungszeit etwas in Ihrer App einrichten möchten. Sie müssen die ursprüngliche Reihenfolge der ursprünglichen Variablen $ LOAD_PATH beibehalten, wenn sie wieder zur neuen Variablen hinzugefügt wird, da sonst einige der wichtigsten Ruby-Klassen verloren gehen.
In der Datei application_controller.rb verwende ich einfach a
Dadurch werden die benutzerdefinierten Bibliotheksdateien für die gesamte Anwendung geladen, dh ich muss nicht in jedem Controller erforderliche Befehle verwenden.
Für mich war dies die Lösung, nach der ich gesucht hatte, und ich dachte, ich würde sie dieser Antwort hinzufügen, um die Informationen weiterzugeben.
quelle