Ich habe ein Juwel, das Code wie folgt hat:
%Vor%Nun ist das Problem, sagen Sie, haben Sie eine Verzeichnisstruktur wie folgt:
%Vor% und main.rb
haben den folgenden Code:
Es kommt mit File Not Found: templates/example.txt
auf. Es würde funktionieren, wenn example.txt
im selben Verzeichnis wie main.rb
wäre, aber nicht, wenn es sich in einem Verzeichnis befindet. Um dieses Problem zu lösen, habe ich ein optionales Argument namens relative_to
in read()
hinzugefügt. Dies erfordert einen absoluten Pfad, so dass das obige Beispiel lauten könnte:
Das funktioniert gut, aber ich denke, es ist ein bisschen hässlich. Gibt es trotzdem, um es so zu machen, dass die Klasse weiß, in welche Datei read()
aufgerufen wird, und den darauf basierenden Pfad ausarbeitet?
Es gibt eine interessante Bibliothek - Ich habe dir gesagt, dass es privat ist . Man kann damit seine Methoden davor schützen, von außen gerufen zu werden. Der Code sucht die Datei der aufrufenden Methode und entfernt sie. Der Täter wird anhand dieser Zeile gefunden:
%Vor%Ich schätze, Sie können es in Ihrem MyGem.read-Code verwenden:
%Vor% Auf diese Weise können Sie Pfade relativ zu Ihrem Mygem-Aufrufer und nicht zu pwd verwenden. Genau wie du es in deinem app/main.rb
versucht hast
Nun, Sie können Anrufer und viel zuverlässiger verwenden, als was die anderen Leute auch sagten.
Setzen Sie in Ihrer Schmuckdatei außerhalb jeder Klasse oder jedes Moduls Folgendes:
%Vor% Dies funktioniert 90% der Zeit, es sei denn das anfordernde Skript führte ein Dir.chdir aus. Der File.expand_path hängt davon ab. Ich fürchte, wenn Ihr Requirer ihr __FILE__
nicht übergibt, können Sie nichts tun, wenn Sie das Arbeitsverzeichnis ändern.
Sie können auch nach Anrufer suchen:
%Vor% Ich würde Ihnen nicht vorschlagen, dies zu tun (der obige Code wird nicht mehr indirekt aufgerufen, weil caller(1)
, siehe Referenz zur Dokumentation auf caller
). Darüber hinaus sollte der obige Regex genauer abgestimmt werden, wenn der Aufruferpfad Doppelpunkte enthalten soll.
Dies sollte für typische Anwendungen funktionieren (ich bin mir nicht sicher, wie resistent es ist, indirekt zu verwenden, wie in madusobwa oben ):
%Vor% Ziehen Sie in Betracht, eine Blockform Ihrer Methode hinzuzufügen, die die Datei nach dem Rendern schließt. In der aktuellen Form zwingen Sie Kunden dazu, ihre Verwendung Ihres Edelsteins mit einem ensure
zu verpacken.
Übernehmen Sie einen Dateipfad String als Argument. In ein Pathname-Objekt konvertieren. Überprüfen Sie, ob der Pfad relativ ist. Wenn ja, dann wandle in absolute um.
%Vor%Sie können diesen Code prägnanter (weniger ausführlich) machen.