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
if dest_prefix != base_prefix
raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
end
while !dest_names.empty? &&
!base_names.empty? &&
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