36
36
# === Example 1: Using Pathname
38
38
# require 'pathname'
39
# p = Pathname.new("/usr/bin/ruby")
40
# size = p.size # 27662
41
# isdir = p.directory? # false
42
# dir = p.dirname # Pathname:/usr/bin
43
# base = p.basename # Pathname:ruby
44
# dir, base = p.split # [Pathname:/usr/bin, Pathname:ruby]
47
# p.each_line { |line| _ }
39
# pn = Pathname.new("/usr/bin/ruby")
40
# size = pn.size # 27662
41
# isdir = pn.directory? # false
42
# dir = pn.dirname # Pathname:/usr/bin
43
# base = pn.basename # Pathname:ruby
44
# dir, base = pn.split # [Pathname:/usr/bin, Pathname:ruby]
47
# pn.each_line { |line| _ }
49
49
# === Example 2: Using standard Ruby
52
# size = File.size(p) # 27662
53
# isdir = File.directory?(p) # false
54
# dir = File.dirname(p) # "/usr/bin"
55
# base = File.basename(p) # "ruby"
56
# dir, base = File.split(p) # ["/usr/bin", "ruby"]
58
# File.open(p) { |f| _ }
59
# File.foreach(p) { |line| _ }
51
# pn = "/usr/bin/ruby"
52
# size = File.size(pn) # 27662
53
# isdir = File.directory?(pn) # false
54
# dir = File.dirname(pn) # "/usr/bin"
55
# base = File.basename(pn) # "ruby"
56
# dir, base = File.split(pn) # ["/usr/bin", "ruby"]
57
# data = File.read(pn)
58
# File.open(pn) { |f| _ }
59
# File.foreach(pn) { |line| _ }
61
61
# === Example 3: Special features
79
# These methods are effectively manipulating a String, because that's all a path
80
# is. Except for #mountpoint?, #children, and #realpath, they don't access the
79
# These methods are effectively manipulating a String, because that's
80
# all a path is. Except for #mountpoint?, #children, #each_child,
81
# #realdirpath and #realpath, they don't access the filesystem.
295
298
# chop_basename(path) -> [pre-basename, basename] or nil
296
299
def chop_basename(path)
297
300
base = File.basename(path)
298
if /\A#{SEPARATOR_PAT}?\z/ =~ base
301
if /\A#{SEPARATOR_PAT}?\z/o =~ base
301
304
return path[0, path.rindex(base)], base
317
320
def prepend_prefix(prefix, relpath)
318
321
if relpath.empty?
319
322
File.dirname(prefix)
320
elsif /#{SEPARATOR_PAT}/ =~ prefix
323
elsif /#{SEPARATOR_PAT}/o =~ prefix
321
324
prefix = File.dirname(prefix)
322
325
prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
433
436
private :cleanpath_conservative
435
def realpath_rec(prefix, unresolved, h)
437
until unresolved.empty?
444
path = prepend_prefix(prefix, File.join(*(resolved + [n])))
446
if h[path] == :resolving
447
raise Errno::ELOOP.new(path)
449
prefix, *resolved = h[path]
455
link_prefix, link_names = split_names(File.readlink(path))
457
prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)
459
prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)
463
h[path] = [prefix, *resolved]
468
return prefix, *resolved
439
# Returns the real (absolute) pathname of +self+ in the actual
440
# filesystem not containing symlinks or useless dots.
442
# All components of the pathname must exist when this method is
445
def realpath(basedir=nil)
446
self.class.new(File.realpath(@path, basedir))
470
private :realpath_rec
473
# Returns a real (absolute) pathname of +self+ in the actual filesystem.
450
# Returns the real (absolute) pathname of +self+ in the actual filesystem.
474
451
# The real pathname doesn't contain symlinks or useless dots.
476
# No arguments should be given; the old behaviour is *obsoleted*.
453
# The last component of the real pathname can be nonexistent.
480
prefix, names = split_names(path)
482
prefix, names2 = split_names(Dir.pwd)
483
names = names2 + names
485
prefix, *names = realpath_rec(prefix, names, {})
486
self.class.new(prepend_prefix(prefix, File.join(*names)))
455
def realdirpath(basedir=nil)
456
self.class.new(File.realdirpath(@path, basedir))
489
459
# #parent returns the parent directory.
688
# p = Pathname("/usr/lib/ruby/1.8")
658
# pn = Pathname("/usr/lib/ruby/1.8")
690
660
# # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
691
661
# Pathname:/usr/lib/ruby/1.8/Env.rb,
692
662
# Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
694
664
# # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
696
666
# Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in
685
# Iterates over the children of the directory
686
# (files and subdirectories, not recursive).
687
# It yields Pathname object for each child.
688
# By default, the yielded pathnames will have enough information to access the files.
689
# If you set +with_directory+ to +false+, then the returned pathnames will contain the filename only.
691
# Pathname("/usr/local").each_child {|f| p f }
692
# #=> #<Pathname:/usr/local/share>
693
# # #<Pathname:/usr/local/bin>
694
# # #<Pathname:/usr/local/games>
695
# # #<Pathname:/usr/local/lib>
696
# # #<Pathname:/usr/local/include>
697
# # #<Pathname:/usr/local/sbin>
698
# # #<Pathname:/usr/local/src>
699
# # #<Pathname:/usr/local/man>
701
# Pathname("/usr/local").each_child(false) {|f| p f }
702
# #=> #<Pathname:share>
704
# # #<Pathname:games>
706
# # #<Pathname:include>
711
def each_child(with_directory=true, &b)
712
children(with_directory).each(&b)
716
716
# #relative_path_from returns a relative path from the argument to the
717
717
# receiver. If +self+ is absolute, the argument must be absolute too. If
771
771
IO.foreach(@path, *args, &block)
774
# Pathname#foreachline is *obsoleted* at 1.8.1. Use #each_line.
775
def foreachline(*args, &block)
776
warn "Pathname#foreachline is obsoleted. Use Pathname#each_line."
777
each_line(*args, &block)
780
# See <tt>IO.read</tt>. Returns all the bytes from the file, or the first +N+
774
# See <tt>IO.read</tt>. Returns all data from the file, or the first +N+ bytes
782
776
def read(*args) IO.read(@path, *args) end
778
# See <tt>IO.binread</tt>. Returns all the bytes from the file, or the first +N+
780
def binread(*args) IO.binread(@path, *args) end
784
782
# See <tt>IO.readlines</tt>. Returns all the lines from the file.
785
783
def readlines(*args) IO.readlines(@path, *args) end
867
865
# See <tt>File.split</tt>. Returns the #dirname and the #basename in an
869
867
def split() File.split(@path).map {|f| self.class.new(f) } end
871
# Pathname#link is confusing and *obsoleted* because the receiver/argument
872
# order is inverted to corresponding system call.
874
warn 'Pathname#link is obsoleted. Use Pathname#make_link.'
875
File.link(old, @path)
878
# Pathname#symlink is confusing and *obsoleted* because the receiver/argument
879
# order is inverted to corresponding system call.
881
warn 'Pathname#symlink is obsoleted. Use Pathname#make_symlink.'
882
File.symlink(old, @path)
974
958
def Pathname.getwd() self.new(Dir.getwd) end
975
959
class << self; alias pwd getwd end
977
# Pathname#chdir is *obsoleted* at 1.8.1.
979
warn "Pathname#chdir is obsoleted. Use Dir.chdir."
980
Dir.chdir(@path, &block)
983
# Pathname#chroot is *obsoleted* at 1.8.1.
985
warn "Pathname#chroot is obsoleted. Use Dir.chroot."
989
961
# Return the entries (files and subdirectories) in the directory, each as a
990
962
# Pathname object.
991
963
def entries() Dir.entries(@path).map {|f| self.class.new(f) } end
994
966
# yields a Pathname object for each entry.
996
968
# This method has existed since 1.8.1.
997
def each_entry(&block) # :yield: p
969
def each_entry(&block) # :yield: pathname
998
970
Dir.foreach(@path) {|f| yield self.class.new(f) }
1001
# Pathname#dir_foreach is *obsoleted* at 1.8.1.
1002
def dir_foreach(*args, &block)
1003
warn "Pathname#dir_foreach is obsoleted. Use Pathname#each_entry."
1004
each_entry(*args, &block)
1007
973
# See <tt>Dir.mkdir</tt>. Create the referenced directory.
1008
974
def mkdir(*args) Dir.mkdir(@path, *args) end
1028
994
# If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the
1029
995
# current directory, not <tt>./</tt>.
1031
def find(&block) # :yield: p
997
def find(&block) # :yield: pathname
1034
1000
Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
1072
1038
alias delete unlink
1074
# This method is *obsoleted* at 1.8.1. Use #each_line or #each_entry.
1075
def foreach(*args, &block)
1076
warn "Pathname#foreach is obsoleted. Use each_line or each_entry."
1077
if FileTest.directory? @path
1078
# For polymorphism between Dir.foreach and IO.foreach,
1079
# Pathname#foreach doesn't yield Pathname object.
1080
Dir.foreach(@path, *args, &block)
1082
IO.foreach(@path, *args, &block)