Reputation: 168091
Converting a relative path foo
with respect to reference point bar
into an absolute path baz
can be done by:
baz = File.expand_path(foo, bar)
How can the opposite of this be done? In other words, given an absolute path baz
and reference point bar
(given as absolute path), how can it be converted into a relative path foo
as below?
foo = File.relative_path(baz, bar)
Please assume that all given paths are normalized in the sense that they do not end with /
in case they are directories:
"/foo/bar"
"/foo/bar/" # No need to consider
and the same applies to all returned paths.
Note that this is not as trivial as stripping away bar
from the initial part of baz
and replacing it with ./
because baz
is not necessarily a descendant of bar
. In general, a number of ../
have to be stacked to reach the common ancestor.
Examples include, but are not limited to:
File.relative_path("/foo/bar/quex", "/foo") # => "bar/quex" (preferred) or
# "./bar/quex"
File.relative_path("/foo", "/foo/bar") # => "../"
File.relative_path("/foo/bar", "/baz/quex") # => "../../foo/bar"
Upvotes: 3
Views: 2503
Reputation: 17020
I believe Pathname#relative_path_from
is what you're looking for. See this answer I gave to another question.
require 'pathname'
first = Pathname.new '/first/path'
second = Pathname.new '/second/path'
relative = second.relative_path_from first
# ../../second/path
first + relative
# /second/path
Upvotes: 9