Como abrir arquivos relativos ao diretório inicial

94

O seguinte falha com Errno::ENOENT: No such file or directory, mesmo se o arquivo existir:

open('~/some_file')

No entanto, posso fazer isso:

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

Eu tenho duas perguntas:

  1. Por que não openprocessa o til apontando para o diretório inicial?
  2. Existe uma maneira mais astuta do que File.expand_path?
Peter
fonte

Respostas:

109
  1. O shell (bash, zsh, etc) é responsável pela expansão do curinga, portanto, em seu primeiro exemplo não há shell, portanto, não há expansão. Usar o til para apontar $HOMEé uma mera convenção; de fato, se você olhar a documentação File.expand_path, ele interpreta corretamente o til, mas é um recurso da própria função, não algo inerente ao sistema subjacente; também File.expand_pathrequer que a $HOMEvariável de ambiente seja definida corretamente. O que nos leva à alternativa possível ...
  2. Experimente isto:

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

Espero que seja liso o suficiente. Pessoalmente, acho que usar uma variável de ambiente é semanticamente mais claro do que usar expand_path.

Roadmaster
fonte
usando o Windows .. tinha que fazeropen(ENV['HOME']+'some_file')
David West
9
Use simplesmente File.join(ENV['HOME'], '/some_file')para que funcione em ambos os casos.
Marcin Bilski
122

Não tenho certeza se isso estava disponível antes do Ruby 1.9.3, mas acho que a solução mais elegante é usar o Dir.homeque faz parte do núcleo.

open("#{Dir.home}/some_file")
Allesklar
fonte
2
Não, não disponível para usuários abaixo de 1.9.3 ( apidock.com/ruby/v1_9_2_180/Dir/home/class ).
Ian Vaughan
12

Em vez de confiar que a $HOMEvariável de ambiente está definida corretamente, o que pode ser um incômodo quando você usa computadores de rede compartilhada para desenvolvimento, você pode obter isso de Ruby usando:

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

Acredito que isso identifica o usuário conectado no momento e obtém seu diretório inicial, em vez de depender da $HOMEvariável de ambiente global que está sendo definida. Esta é uma solução alternativa para o que foi dito acima.

Voke Ransom Anighoro
fonte
2

Eu descobri o problema do til e um patch foi criado para adicionar absolute_path que trata o til como um caractere comum.

Da documentação do arquivo:

absolute_path(file_name [, dir_string] )  abs_file_name

Converte um nome de caminho em um nome de caminho absoluto. Caminhos relativos são referenciados a partir do diretório de trabalho atual do processo, a menos que dir_string seja fornecido, caso em que será usado como ponto de partida. Se o nome do caminho fornecido começar com “~”, ele NÃO será expandido, será tratado como um nome de diretório normal.

Charles Edward Thornton
fonte