Jak otwierać pliki względem katalogu domowego

95

Poniższy błąd kończy się niepowodzeniem Errno::ENOENT: No such file or directory, nawet jeśli plik istnieje:

open('~/some_file')

Jednak mogę to zrobić:

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

Mam dwa pytania:

  1. Dlaczego opentylda nie jest przetwarzana jako wskazująca na katalog domowy?
  2. Czy jest lepszy sposób niż File.expand_path?
Piotr
źródło

Odpowiedzi:

109
  1. Powłoka (bash, zsh itp.) Jest odpowiedzialna za ekspansję symboli wieloznacznych, więc w pierwszym przykładzie nie ma powłoki, a więc nie ma ekspansji. Używanie tyldy do wskazywania $HOMEjest zwykłą konwencją; rzeczywiście, jeśli spojrzysz na dokumentację File.expand_path, poprawnie zinterpretuje ona tyldę, ale jest to cecha samej funkcji, a nie coś nieodłącznego dla systemu bazowego; również File.expand_pathwymaga $HOMEzmiennej środowiskowej być ustawione poprawnie. Które prowadzą nas do możliwej alternatywy ...
  2. Spróbuj tego:

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

Mam nadzieję, że jest wystarczająco zgrabny. Osobiście uważam, że używanie zmiennej środowiskowej jest semantycznie jaśniejsze niż używanie expand_path.

Roadmaster
źródło
używając Windows .. musiał zrobićopen(ENV['HOME']+'some_file')
David West
9
Użyj po prostu, File.join(ENV['HOME'], '/some_file')aby działał w obu przypadkach.
Marcin Bilski
123

Nie jestem pewien, czy to było dostępne przed Ruby 1.9.3, ale uważam, że najbardziej eleganckim rozwiązaniem jest użycie Dir.homeczęści rdzenia.

open("#{Dir.home}/some_file")
allesklar
źródło
2
Nie, niedostępne dla użytkowników poniżej 1.9.3 ( apidock.com/ruby/v1_9_2_180/Dir/home/class ).
Ian Vaughan
12

Zamiast polegać na $HOMEpoprawnym ustawieniu zmiennej środowiskowej, co może być kłopotliwe, gdy używasz współdzielonych komputerów w sieci do programowania, możesz uzyskać to od Rubiego za pomocą:

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

Uważam, że to identyfikuje aktualnie zalogowanego użytkownika i pobiera jego katalog domowy, zamiast polegać na $HOMEustawianej globalnej zmiennej środowiskowej. Uważam, że jest to alternatywne rozwiązanie do powyższego.

Voke Ransom Anighoro
źródło
2

Odkryłem problem tyldy i stworzono łatkę do dodania, absolute_path która traktuje tyldę jak zwykły znak.

Z dokumentacji pliku:

absolute_path(file_name [, dir_string] )  abs_file_name

Konwertuje nazwę ścieżki na bezwzględną nazwę ścieżki. Względne ścieżki są przywoływane z bieżącego katalogu roboczego procesu, chyba że podano dir_string, w którym to przypadku zostanie użyty jako punkt początkowy. Jeśli podana nazwa ścieżki zaczyna się od „~”, NIE jest rozwijana, jest traktowana jak normalna nazwa katalogu.

Charles Edward Thornton
źródło