In: |
pathname.rb
|
Parent: | Object |
Dir
# File pathname.rb, line 12 def initialize(path) @path = path.to_str.dup @path.freeze if /\0/ =~ @path raise ArgumentError, "pathname contains \\0: #{@path.inspect}" end end
# File pathname.rb, line 421 def Pathname.glob(*args) if block_given? Dir.glob(*args) {|f| yield Pathname.new(f) } else Dir.glob(*args).map {|f| Pathname.new(f) } end end
# File pathname.rb, line 21 def ==(other) return false unless Pathname === other other.to_s == @path end
# File pathname.rb, line 28 def <=>(other) return nil unless Pathname === other @path.tr('/', "\0") <=> other.to_s.tr('/', "\0") end
cleanpath returns clean pathname of self which is without consecutive slashes and useless dots.
If true is given as the optional argument consider_symlink, symbolic links are considered. It makes more dots are retained.
cleanpath doesn’t access actual filesystem.
# File pathname.rb, line 55 def cleanpath(consider_symlink=false) if consider_symlink cleanpath_conservative else cleanpath_aggressive end end
realpath returns a real pathname of self in actual filesystem. The real pathname doesn’t contain a symlink and useless dots.
It returns absolute pathname.
# File pathname.rb, line 113 def realpath(*args) unless args.empty? warn "The argument for Pathname#realpath is obsoleted." end force_absolute = args.fetch(0, true) if %{\A/} =~ @path top = '/' unresolved = @path.scan(%{[^/]+}) elsif force_absolute # Although POSIX getcwd returns a pathname which contains no symlink, # 4.4BSD-Lite2 derived getcwd may return the environment variable $PWD # which may contain a symlink. # So the return value of Dir.pwd should be examined. top = '/' unresolved = Dir.pwd.scan(%{[^/]+}) + @path.scan(%{[^/]+}) else top = '' unresolved = @path.scan(%{[^/]+}) end resolved = [] until unresolved.empty? case unresolved.last when '.' unresolved.pop when '..' resolved.unshift unresolved.pop else loop_check = {} while (stat = File.lstat(path = top + unresolved.join('/'))).symlink? symlink_id = "#{stat.dev}:#{stat.ino}" raise Errno::ELOOP.new(path) if loop_check[symlink_id] loop_check[symlink_id] = true if %{\A/} =~ (link = File.readlink(path)) top = '/' unresolved = link.scan(%{[^/]+}) else unresolved[-1,1] = link.scan(%{[^/]+}) end end next if (filename = unresolved.pop) == '.' if filename != '..' && resolved.first == '..' resolved.shift else resolved.unshift filename end end end if top == '/' resolved.shift while resolved[0] == '..' end if resolved.empty? Pathname.new(top.empty? ? '.' : '/') else Pathname.new(top + resolved.join('/')) end end
parent method returns parent directory.
If self is `.’, `..’ is returned. Otherwise, `..’ is joined to self.
# File pathname.rb, line 178 def parent if @path == '.' Pathname.new('..') else self.join('..') end end
mountpoint? method returns true if self points a mountpoint.
# File pathname.rb, line 187 def mountpoint? begin stat1 = self.lstat stat2 = self.parent.lstat stat1.dev == stat2.dev && stat1.ino == stat2.ino || stat1.dev != stat2.dev rescue Errno::ENOENT false end end
root? method is a predicate for root directory. I.e. it returns true if the pathname consists of consecutive slashes.
It doesn’t access actual filesystem. So it may return false for some pathnames which points root such as "/usr/..".
# File pathname.rb, line 204 def root? %{\A/+\z} =~ @path ? true : false end
absolute? method is a predicate for absolute pathname. It returns true if self is beginning with a slash.
# File pathname.rb, line 210 def absolute? %{\A/} =~ @path ? true : false end
relative? method is a predicate for relative pathname. It returns true unless self is beginning with a slash.
# File pathname.rb, line 216 def relative? !absolute? end
each_filename iterates over self for each filename components.
# File pathname.rb, line 221 def each_filename @path.scan(%{[^/]+}) { yield $& } end
Pathname#+ return new pathname which is concatenated with self and an argument. If self is the current working directory `.’ or the argument is absolute pathname, the argument is just returned. If the argument is `.’, self is returned.
# File pathname.rb, line 231 def +(other) other = Pathname.new(other) unless Pathname === other if @path == '.' || other.absolute? other elsif other.to_s == '.' self elsif %{/\z} =~ @path Pathname.new(@path + other.to_s) else Pathname.new(@path + '/' + other.to_s) end end
Pathname#join joins pathnames.
path0.join(path1, … pathN) is same as path0 + path1 + … + pathN.
# File pathname.rb, line 247 def join(*args) args.map! {|arg| Pathname === arg ? arg : Pathname.new(arg) } args.inject(self) {|pathname, arg| pathname + arg } end
Pathname#children returns the children of the directory as an array of pathnames.
By default, the returned pathname can be used to access the corresponding file in the directory. This is because the pathname contains self as a prefix unless self is `.’.
If false is given for the optional argument `with_directory’, just filenames of children is returned. In this case, the returned pathname cannot be used directly to access the corresponding file when self doesn’t point working directory.
Note that the result never contain the entry `.’ and `..’ in the directory because they are not child.
This method is exist since 1.8.1.
# File pathname.rb, line 268 def children(with_directory=true) with_directory = false if @path == '.' result = [] Dir.foreach(@path) {|e| next if e == '.' || e == '..' if with_directory result << Pathname.new(File.join(@path, e)) else result << Pathname.new(e) end } result end
Pathname#relative_path_from returns a relative path from the argument to self. 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 actual filesystem. It assumes no symlinks.
ArgumentError is raised when it cannot find a relative path.
This method is exist since 1.8.1.
# File pathname.rb, line 293 def relative_path_from(base_directory) if self.absolute? != base_directory.absolute? raise ArgumentError, "relative path between absolute and relative path: #{self.inspect}, #{base_directory.inspect}" end dest = [] self.cleanpath.each_filename {|f| next if f == '.' dest << f } base = [] base_directory.cleanpath.each_filename {|f| next if f == '.' base << f } while !base.empty? && !dest.empty? && base[0] == dest[0] base.shift dest.shift end if base.include? '..' raise ArgumentError, "base_directory has ..: #{base_directory.inspect}" end base.fill '..' relpath = base + dest if relpath.empty? Pathname.new(".") else Pathname.new(relpath.join('/')) end end
Pathname#each_line iterates over lines of the file. It’s yields a String object for each line.
This method is exist since 1.8.1.
# File pathname.rb, line 337 def each_line(*args, &block) IO.foreach(@path, *args, &block) end
Pathname#foreachline is obsoleted at 1.8.1.
# File pathname.rb, line 341 def foreachline(*args, &block) # compatibility to 1.8.0. obsoleted. warn "Pathname#foreachline is obsoleted. Use Pathname#each_line." each_line(*args, &block) end
# File pathname.rb, line 375 def expand_path(*args) Pathname.new(File.expand_path(@path, *args)) end
Pathname#link is confusing and obsoleted because the receiver/argument order is inverted to corresponding system call.
# File pathname.rb, line 380 def link(old) warn 'Pathname#link is obsoleted. Use Pathname#make_link.' File.link(old, @path) end
Pathname#symlink is confusing and obsoleted because the receiver/argument order is inverted to corresponding system call.
# File pathname.rb, line 387 def symlink(old) warn 'Pathname#symlink is obsoleted. Use Pathname#make_symlink.' File.symlink(old, @path) end
Pathname#chdir is obsoleted at 1.8.1.
# File pathname.rb, line 434 def chdir(&block) # compatibility to 1.8.0. warn "Pathname#chdir is obsoleted. Use Dir.chdir." Dir.chdir(@path, &block) end
Pathname#chroot is obsoleted at 1.8.1.
# File pathname.rb, line 441 def chroot # compatibility to 1.8.0. warn "Pathname#chroot is obsoleted. Use Dir.chroot." Dir.chroot(@path) end
Pathname#each_entry iterates over entries of the directory. It’s yields Pathname objects for each entry.
This method is exist since 1.8.1.
# File pathname.rb, line 453 def each_entry(&block) Dir.foreach(@path) {|f| yield Pathname.new(f) } end # Pathname#dir_foreach is obsoleted at 1.8.1. # def dir_foreach(*args, &block) # compatibility to 1.8.0. obsoleted. warn "Pathname#dir_foreach is obsoleted. Use Pathname#each_entry." each_entry(*args, &block) end def mkdir(*args) Dir.mkdir(@path, *args) end def opendir(&block) Dir.open(@path, &block) end end
Pathname#dir_foreach is obsoleted at 1.8.1.
# File pathname.rb, line 457 def dir_foreach(*args, &block) # compatibility to 1.8.0. obsoleted. warn "Pathname#dir_foreach is obsoleted. Use Pathname#each_entry." each_entry(*args, &block) end