So öffnen Sie Dateien relativ zum Ausgangsverzeichnis

94

Folgendes schlägt fehl Errno::ENOENT: No such file or directory, auch wenn die Datei vorhanden ist:

open('~/some_file')

Ich kann dies jedoch tun:

open(File.expand_path('~/some_file'))

Ich habe zwei Fragen:

  1. Warum openwird die Tilde nicht so verarbeitet, dass sie auf das Ausgangsverzeichnis verweist?
  2. Gibt es einen schlaueren Weg als File.expand_path?
Peter
quelle

Antworten:

109
  1. Die Shell (bash, zsh usw.) ist für die Platzhaltererweiterung verantwortlich. In Ihrem ersten Beispiel gibt es also keine Shell und daher keine Erweiterung. Das Verwenden der Tilde zum Zeigen $HOMEist eine bloße Konvention; Wenn Sie sich die Dokumentation ansehen File.expand_path, wird die Tilde zwar korrekt interpretiert, aber es ist ein Merkmal der Funktion selbst, das dem zugrunde liegenden System nicht eigen ist. Außerdem File.expand_pathmuss die $HOMEUmgebungsvariable korrekt eingestellt sein. Was uns zur möglichen Alternative bringt ...
  2. Versuche dies:

    open(ENV['HOME']+'/some_file')

Ich hoffe es ist glatt genug. Ich persönlich denke, die Verwendung einer Umgebungsvariablen ist semantisch klarer als die Verwendung expand_path.

Roadmaster
quelle
mit Windows .. musste tunopen(ENV['HOME']+'some_file')
David West
9
Verwenden Sie es einfach File.join(ENV['HOME'], '/some_file'), damit es in beiden Fällen funktioniert.
Marcin Bilski
122

Ich bin mir nicht sicher, ob dies vor Ruby 1.9.3 verfügbar war, aber ich finde, dass die eleganteste Lösung darin besteht, das zu verwenden, Dir.homewas Teil des Kerns ist.

open("#{Dir.home}/some_file")
allesklar
quelle
2
Nein, nicht verfügbar für Benutzer unter 1.9.3 ( apidock.com/ruby/v1_9_2_180/Dir/home/class ).
Ian Vaughan
12

Anstatt sich darauf zu verlassen, dass die $HOMEUmgebungsvariable richtig eingestellt ist, was ein Problem sein kann, wenn Sie gemeinsam genutzte Netzwerkcomputer für die Entwicklung verwenden, können Sie dies von Ruby mit folgenden Informationen erhalten:

require 'etc'
open ("#{Etc.getpwuid.dir}/some_file")

Ich glaube, dies identifiziert den aktuell angemeldeten Benutzer und erhält sein Ausgangsverzeichnis, anstatt sich auf die festgelegte globale $HOMEUmgebungsvariable zu verlassen. Dies ist meiner Meinung nach eine alternative Lösung zu den oben genannten.

Voke Ransom Anighoro
quelle
2

Ich habe das Tilde-Problem entdeckt und einen Patch erstellt, absolute_path der Tilde als gewöhnliches Zeichen behandelt.

Aus der Dateidokumentation:

absolute_path(file_name [, dir_string] )  abs_file_name

Konvertiert einen Pfadnamen in einen absoluten Pfadnamen. Relative Pfade werden aus dem aktuellen Arbeitsverzeichnis des Prozesses referenziert, sofern nicht dir_string angegeben ist. In diesem Fall wird es als Ausgangspunkt verwendet. Wenn der angegebene Pfadname mit einem "~" beginnt, wird er NICHT erweitert, sondern als normaler Verzeichnisname behandelt.

Charles Edward Thornton
quelle