relative_path_from(base_directory)
public
#relative_path_from returns
a relative path from the argument to the receiver. If self is
absolute, the argument must be absolute too. If self is relative,
the argument must be relative too.
#relative_path_from
doesn’t access the filesystem. It assumes no symlinks.
ArgumentError is raised when it cannot find a relative path.
This method has existed since 1.8.1.
Show source
def relative_path_from(base_directory)
dest_directory = self.cleanpath.to_s
base_directory = base_directory.cleanpath.to_s
dest_prefix = dest_directory
dest_names = []
while r = chop_basename(dest_prefix)
dest_prefix, basename = r
dest_names.unshift basename if basename != '.'
end
base_prefix = base_directory
base_names = []
while r = chop_basename(base_prefix)
base_prefix, basename = r
base_names.unshift basename if basename != '.'
end
unless SAME_PATHS[dest_prefix, base_prefix]
raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
end
while !dest_names.empty? &&
!base_names.empty? &&
SAME_PATHS[dest_names.first, base_names.first]
dest_names.shift
base_names.shift
end
if base_names.include? '..'
raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
end
base_names.fill('..')
relpath_names = base_names + dest_names
if relpath_names.empty?
Pathname.new('.')
else
Pathname.new(File.join(*relpath_names))
end
end