Was bedeutet __FILE__ in Ruby?

216

Ich sehe das die ganze Zeit in Ruby:

require File.dirname(__FILE__) + "/../../config/environment"  

Was heißt __FILE__das

Josh Moore
quelle

Antworten:

144

Es ist ein Verweis auf den aktuellen Dateinamen. In der Datei foo.rb, __FILE__würde interpretiert als "foo.rb".

Edit: Ruby 1.9.2 und 1.9.3 scheinen sich ein wenig anders zu verhalten als das, was Luke Bayes in seinem Kommentar gesagt hat . Mit diesen Dateien:

# test.rb
puts __FILE__
require './dir2/test.rb'
# dir2/test.rb
puts __FILE__

Laufen ruby test.rbwird ausgegeben

test.rb
/full/path/to/dir2/test.rb
Geoff
quelle
87
Diese Antwort ist nicht korrekt. DATEI ist der "relative" Pfad zur Datei aus dem aktuellen Ausführungsverzeichnis - nicht absolut. Sie müssen File.expand_path ( FILE ) verwenden, um den absoluten Pfad zu erhalten
Luke Bayes
7
Doppelte Unterstriche wurden im obigen Kommentar automatisch entfernt.
Luke Bayes
1
Trifft dies in Ruby 1.9.2 noch zu?
Zasz
4
@Zasz Es funktioniert etwas anders in 1.9.2. Die ursprünglich geladene Datei hat eine relative __FILE__, aber andere enthaltene / erforderliche Dateien haben absolute Pfade.
Geoff
9
@LukeBayes Sie können Unterstriche und andere Sonderzeichen in Stack Overflow-Kommentaren beibehalten, indem Sie den wörtlichen Text mit Backticks umgeben. Schreiben Sie `__FILE__`, um zu bekommen __FILE__.
Rory O'Kane
62

Der Wert von __FILE__ist ein relativer Pfad, der beim Laden Ihrer Datei erstellt und gespeichert (aber nie aktualisiert) wird. Dies bedeutet, dass Dir.chdirdieser Pfad falsch erweitert wird , wenn Sie an einer anderen Stelle in Ihrer Anwendung Anrufe tätigen .

puts __FILE__
Dir.chdir '../../'
puts __FILE__

Eine Problemumgehung für dieses Problem besteht darin, den erweiterten Wert __FILE__außerhalb eines Anwendungscodes zu speichern . Solange Ihre requireAnweisungen oben in Ihren Definitionen stehen (oder zumindest vor Aufrufen von Dir.chdir), ist dieser Wert nach dem Ändern der Verzeichnisse weiterhin nützlich.

$MY_FILE_PATH = File.expand_path(File.dirname(__FILE__))

# open class and do some stuff that changes directory

puts $MY_FILE_PATH
Luke Bayes
quelle
This means that if you have any calls to Dir.chdir anywhere else in your application, this path will expand incorrectly.Der Pfad wurde unter meinem Test korrekt erweitert. Meine Ruby-Version ist 2.3.7, möglicherweise hat die neuere Ruby-Version dieses Problem behoben.
Alec.Zhou
28

__FILE__ ist der Dateiname mit der Erweiterung der Datei, die den ausgeführten Code enthält.

In foo.rb, __FILE__wäre "foo.rb".

Wenn foo.rbin der dir wäre /home/joshdann File.dirname(__FILE__)würde zurückkehren /home/josh.

Ethan
quelle
Genau danach suchen. +1: =) @Ethan
KM Rakibul Islam
1
Ein Link zur Dokumentation hier
Ross Attrill
17

In Ruby, der Windows-Version sowieso, habe ich gerade überprüft und __FILE__enthält nicht den vollständigen Pfad zur Datei. Stattdessen enthält es den Pfad zur Datei relativ zu dem Ort, von dem aus sie ausgeführt wird.

In PHP __FILE__ist der vollständige Pfad (was meiner Meinung nach vorzuziehen ist). Aus diesem Grund müssen Sie Folgendes verwenden, um Ihre Pfade in Ruby portierbar zu machen:

File.expand_path(File.dirname(__FILE__) + "relative/path/to/file")

Ich sollte beachten, dass in Ruby 1.9.1 __FILE__der vollständige Pfad zur Datei enthalten ist. Die obige Beschreibung war für die Verwendung von Ruby 1.8.7 vorgesehen.

Um sowohl mit Ruby 1.8.7 als auch mit 1.9.1 kompatibel zu sein (nicht sicher über 1.9), sollten Sie Dateien mit dem oben gezeigten Konstrukt benötigen.

Matt Wolfe
quelle
Sie müssen Ihrem relativen Pfad einen Schrägstrich voranstellen:File.expand_path(File.dirname(__FILE__) + "/relative/path/to/file")
Felix Rabe
3
Sie sollten das Verzeichnis-Trennzeichen niemals fest codieren. Verwenden Sie stattdessen File.join: File.expand_path( File.join( File.dirname(__FILE__), "relative", "path", "to", "file") )
Andrew Hodgkinson