Как открыть файлы по отношению к домашней директории

Сбой <<20 > , если файл существует:

open('~/some_file')

Однако я могу это сделать:

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

У меня есть два вопроса:

  • Почему open не обрабатывает тильду как указывающую на домашний каталог?
  • Есть ли более гладкий способ, чем File.expand_path?

Ответ 1

  • Оболочка (bash, zsh и т.д.) отвечает за расширение подстановочных знаков, поэтому в вашем первом примере нет оболочки, следовательно нет расширения. Использование тильды, указывающей на $HOME, является простым соглашением; действительно, если вы посмотрите на документацию для File.expand_path, она правильно интерпретирует тильду, но это функция самой функции, а не что-то, что присуще базовой системе; Кроме того, File.expand_path требует правильной установки переменной среды $HOME. Что приводит нас к возможной альтернативе...
  • Попробуйте следующее:

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

Я надеюсь, что это будет достаточно. Я лично считаю, что использование переменной окружения семантически яснее, чем использование expand_path.

Ответ 2

Не уверен, что это было доступно до Ruby 1.9.3, но я считаю, что самым изящным решением является использование Dir.home, который является частью ядра.

open("#{Dir.home}/some_file")

Ответ 3

Вместо того, чтобы полагаться на переменную среды $HOME, которая устанавливается правильно, что может быть проблемой при использовании общих сетевых компьютеров для разработки, вы можете получить это от Ruby, используя:

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

Я считаю, что это идентифицирует текущего зарегистрированного пользователя и получает их домашний каталог, а не полагается на глобальную переменную окружения $HOME. Это альтернативное решение вышеизложенного. Я полагаю.

Ответ 4

Я обнаружил проблему тильды, и был создан патч, чтобы добавить absolute_path который рассматривает тильду как обычный характер.

В документации к файлу:

absolute_path(file_name [, dir_string] ) → abs_file_name

Преобразует путь к абсолютному пути. Относительные пути ссылаются на текущий рабочий каталог процесса, если не указана dir_string, и в этом случае он будет использоваться в качестве отправной точки. Если заданный путь начинается с "~", он НЕ расширяется, он рассматривается как нормальное имя каталога.