How to open files relative to home directory

Ruby

Ruby Problem Overview


The following fails with Errno::ENOENT: No such file or directory, even if the file exists:

open('~/some_file')

However, I can do this:

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

I have two questions:

  1. Why doesn't open process the tilde as pointing to the home directory?
  2. Is there a slicker way than File.expand_path?

Ruby Solutions


Solution 1 - Ruby

Not sure if this was available before Ruby 1.9.3 but I find that the most elegant solution is to use Dir.home which is part of core.

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

Solution 2 - Ruby

  1. The shell (bash, zsh, etc) is responsible for wildcard expansion, so in your first example there's no shell, hence no expansion. Using the tilde to point to $HOME is a mere convention; indeed, if you look at the documentation for File.expand_path, it correctly interprets the tilde, but it's a feature of the function itself, not something inherent to the underlying system; also, File.expand_path requires the $HOME environment variable to be correctly set. Which bring us to the possible alternative...

  2. Try this:

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

I hope it's slick enough. I personally think using an environment variable is semantically clearer than using expand_path.

Solution 3 - Ruby

Instead of relying on the $HOME environment variable being set correctly, which could be a hassle when you use shared network computers for development, you could get this from Ruby using:

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

I believe this identifies the current logged-in user and gets their home directory rather than relying on the global $HOME environment variable being set. This is an alternative solution to the above I reckon.

Solution 4 - Ruby

I discovered the tilde problem, and a patch was created to add absolute_path which treats tilde as an ordinary character.

From the File documentation:

absolute_path(file_name [, dir_string] ) → abs_file_name

> Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. If the given pathname starts with a “~” it is NOT expanded, it is treated as a normal directory name.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeterView Question on Stackoverflow
Solution 1 - RubyallesklarView Answer on Stackoverflow
Solution 2 - RubyRoadmasterView Answer on Stackoverflow
Solution 3 - RubyRansomView Answer on Stackoverflow
Solution 4 - RubyCharles Edward ThorntonView Answer on Stackoverflow