Method: Path#relative_path_from

Defined in:
lib/epath/implementation.rb

#relative_path_from(base_directory) ⇒ Object Also known as: relative_to, %

#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.

Raises:

  • (ArgumentError)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/epath/implementation.rb', line 107

def relative_path_from(base_directory)
  dest = clean.path
  base = Path.new(base_directory).clean.path
  dest_prefix, dest_names = split_names(dest)
  base_prefix, base_names = split_names(base)

  unless SAME_PATHS[dest_prefix, base_prefix]
    raise ArgumentError, "different prefix: #{self.inspect} and #{base_directory.inspect}"
  end
  while d = dest_names.first and b = base_names.first and SAME_PATHS[d, b]
    dest_names.shift
    base_names.shift
  end
  raise ArgumentError, "base_directory has ..: #{base_directory.inspect}" if base_names.include? '..'
  # the number of names left in base is the ones we have to climb
  names = base_names.fill('..').concat(dest_names)
  return Path.new('.') if names.empty?
  Path.new(*names)
end