Class: Pathname

Inherits:
String show all
Extended by:
FFI::Library, Facade
Defined in:
lib/pathname2.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =

The version of the pathname2 library

'1.7.3'
MAXPATH =

The maximum length of a path

1024

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from String

#to_path, #wincode

Constructor Details

#initialize(path) ⇒ Pathname

Creates and returns a new Pathname object.

On platforms that define File::ALT_SEPARATOR, all forward slashes are replaced with the value of File::ALT_SEPARATOR. On MS Windows, for example, all forward slashes are replaced with backslashes.

File URL’s will be converted to Pathname objects, e.g. the file URL “file:///C:/Documents%20and%20Settings” will become ‘C:Documents and Settings’.

Examples:

Pathname.new("/foo/bar/baz")
Pathname.new("foo")
Pathname.new("file:///foo/bar/baz")
Pathname.new("C:\\Documents and Settings\\snoopy")


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/pathname2.rb', line 129

def initialize(path)
  if path.length > MAXPATH
    msg = "string too long.  maximum string length is " + MAXPATH.to_s
    raise ArgumentError, msg
  end

  @sep = File::ALT_SEPARATOR || File::SEPARATOR
  @win = File::ALT_SEPARATOR

  # Handle File URL's. The separate approach for Windows is necessary
  # because Ruby's URI class does not (currently) parse absolute file URL's
  # properly when they include a drive letter.
  if @win
    wpath = path.wincode

    if PathIsURLW(wpath)
      buf = FFI::MemoryPointer.new(:char, MAXPATH)
      len = FFI::MemoryPointer.new(:ulong)
      len.write_ulong(buf.size)

      if PathCreateFromUrlW(wpath, buf, len, 0) == 0
        path = buf.read_string(path.size * 2).tr(0.chr, '')
      else
        raise Error, "invalid file url: #{path}"
      end
    end
  else
    if path.index('file:///', 0)
      require 'uri'
      path = URI::Parser.new.unescape(path)[7..-1]
    end
  end

  # Convert forward slashes to backslashes on Windows
  path = path.tr(File::SEPARATOR, File::ALT_SEPARATOR) if @win

  super(path)
end

Class Method Details

.pwdObject Also known as: getwd

Returns the expanded path of the current working directory.

Synonym for Pathname.new(Dir.pwd).



105
106
107
# File 'lib/pathname2.rb', line 105

def self.pwd
  new(Dir.pwd)
end

Instance Method Details

#+(string) ⇒ Object Also known as: /

Adds two Pathname objects together, or a Pathname and a String. It also automatically cleans the Pathname.

Adding a root path to an existing path merely replaces the current path. Adding ‘.’ to an existing path does nothing.

Example:

path1 = '/foo/bar'
path2 = '../baz'
path1 + path2 # '/foo/baz'


678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
# File 'lib/pathname2.rb', line 678

def +(string)
  unless string.kind_of?(Pathname)
    string = self.class.new(string)
  end

  # Any path plus "." is the same directory
  return self if string == "."
  return string if self == "."

  # Use the builtin PathAppend() function if on Windows - much easier
  if @win
    path = FFI::MemoryPointer.new(:char, MAXPATH)
    path.write_string(self.dup.wincode)
    more = FFI::MemoryPointer.from_string(string.wincode)

    PathAppendW(path, more)

    path = path.read_string(path.size).split("\000\000").first.delete(0.chr)

    return self.class.new(path) # PathAppend cleans automatically
  end

  # If the string is an absolute directory, return it
  return string if string.absolute?

  array = to_a + string.to_a
  new_string = array.join(@sep)

  unless relative? || @win
    temp = @sep + new_string # Add root path back if needed
    new_string.replace(temp)
  end

  self.class.new(new_string).clean
end

#<=>(string) ⇒ Object

Compares two Pathname objects. Note that Pathnames may only be compared against other Pathnames, not strings. Otherwise nil is returned.

Example:

path1 = Pathname.new('/usr/local')
path2 = Pathname.new('/usr/local')
path3 = Pathname.new('/usr/local/bin')

path1 <=> path2 # => 0
path1 <=> path3 # => -1


583
584
585
586
# File 'lib/pathname2.rb', line 583

def <=>(string)
  return nil unless string.kind_of?(Pathname)
  super
end

#[](index, length = nil) ⇒ Object

Returns the path component at index, up to length components, joined by the path separator. If the index is a Range, then that is used instead and the length is ignored.

Keep in mind that on MS Windows the drive letter is the first element.

Examples:

path = Pathname.new('/home/john/source/ruby')
path[0]    # => 'home'
path[1]    # => 'john'
path[0, 3] # => '/home/john/source'
path[0..1] # => '/home/john'

path = Pathname.new('C:/Documents and Settings/John/Source/Ruby')
path[0]    # => 'C:\'
path[1]    # => 'Documents and Settings'
path[0, 3] # => 'C:\Documents and Settings\John'
path[0..1] # => 'C:\Documents and Settings'


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/pathname2.rb', line 375

def [](index, length=nil)
  if index.is_a?(Fixnum)
    if length
      path = File.join(to_a[index, length])
    else
      path = to_a[index]
    end
  elsif index.is_a?(Range)
    if length
      warn 'Length argument ignored'
    end
    path = File.join(to_a[index])
  else
    raise TypeError, "Only Fixnums and Ranges allowed as first argument"
  end

  if path && @win
    path = path.tr("/", "\\")
  end

  path
end

#absolute?Boolean

Returns whether or not the path is an absolute path.

Example:

Pathname.new('/usr/bin').absolute? # => true
Pathname.new('usr').absolute?      # => false

Returns:

  • (Boolean)


723
724
725
# File 'lib/pathname2.rb', line 723

def absolute?
  !relative?
end

#ascendObject

Yields the path, minus one component on each iteration, as a new Pathname object, ending with the root path.

Example:

path = Pathname.new('/usr/local/bin')

path.ascend{ |name|
   puts name
}

First iteration  => '/usr/local/bin'
Second iteration => '/usr/local'
Third iteration  => '/usr'
Fourth iteration => '/'


456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/pathname2.rb', line 456

def ascend
  if root?
    yield root
    return
  end

  n = to_a.length

  while n > 0
    path = to_a[0..n-1].join(@sep)
    if absolute?
      if @win && unc?
        path = "\\\\" << path
      end
      unless @win
        path = root << path
      end
    end

    path = self.class.new(path)
    yield path

    if @win && unc?
      break if path.root?
    end

    n -= 1
  end

  # Yield the root directory if an absolute path (and not Windows)
  unless @win
    yield root if absolute?
  end
end

#basename(*args) ⇒ Object

File.basename



989
990
991
# File 'lib/pathname2.rb', line 989

def basename(*args)
  self.class.new(File.basename(self, *args))
end

#cd(*args, &block) ⇒ Object

FileUtils.cd



1004
1005
1006
# File 'lib/pathname2.rb', line 1004

def cd(*args, &block)
  FileUtils.cd(self, *args, &block)
end

#chdir(&block) ⇒ Object

Dir.chdir



907
908
909
# File 'lib/pathname2.rb', line 907

def chdir(&block)
  Dir.chdir(self, &block)
end

#children(with_directory = true) ⇒ Object

Returns the children of the directory, files and subdirectories, as an array of Pathname objects. If you set with_directory to false, then the returned pathnames will contain the filename only.

Note that the result never contain the entries ‘.’ and ‘..’ in the the directory because they are not children. Also note that this method is not recursive.

Example:

path = Pathname.new(‘/usr/bin’) path.children # => [‘/usr/bin/ruby’, ‘/usr/bin/perl’, …] path.children(false) # => [‘ruby’, ‘perl’, …]



211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/pathname2.rb', line 211

def children(with_directory = true)
  with_directory = false if self == '.'
  result = []
  Dir.foreach(self) { |file|
    next if file == '.' || file == '..'
    if with_directory
      result << self.class.new(File.join(self, file))
    else
      result << self.class.new(file)
    end
  }
  result
end

#chmod(mode) ⇒ Object

File.chmod



929
930
931
# File 'lib/pathname2.rb', line 929

def chmod(mode)
  File.chmod(mode, self)
end

#chown(owner, group) ⇒ Object

File.chown



939
940
941
# File 'lib/pathname2.rb', line 939

def chown(owner, group)
  File.chown(owner, group, self)
end

#cleanObject Also known as: cleanpath

Removes unnecessary ‘.’ paths and ellides ‘..’ paths appropriately. This method is non-destructive.

Example:

path = Pathname.new('/usr/./local/../bin')
path.clean # => '/usr/bin'


750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
# File 'lib/pathname2.rb', line 750

def clean
  return self if self.empty?

  if @win
    ptr = FFI::MemoryPointer.new(:char, MAXPATH)
    if PathCanonicalizeW(ptr, self.wincode)
      return self.class.new(ptr.read_string(ptr.size).delete(0.chr))
    else
      return self
    end
  end

  final = []

  to_a.each{ |element|
    next if element == "."
    final.push(element)
    if element == ".." && self != ".."
      2.times{ final.pop }
    end
  }

  final = final.join(@sep)
  final = root._plus_(final) if root != "."
  final = "." if final.empty?

  self.class.new(final)
end

#clean!Object Also known as: cleanpath!

Identical to Pathname#clean, except that it modifies the receiver in place.



784
785
786
# File 'lib/pathname2.rb', line 784

def clean!
  self.replace(clean)
end

#compare_file(file) ⇒ Object

FileUtils.compare_file



1083
1084
1085
# File 'lib/pathname2.rb', line 1083

def compare_file(file)
  FileUtils.compare_file(self, file)
end

#copy_entry(*args) ⇒ Object

FileUtils.copy_entry



1108
1109
1110
# File 'lib/pathname2.rb', line 1108

def copy_entry(*args)
  FileUtils.copy_entry(self, *args)
end

#copy_file(*args) ⇒ Object

FileUtils.copy_file



1093
1094
1095
# File 'lib/pathname2.rb', line 1093

def copy_file(*args)
  FileUtils.copy_file(self, *args)
end

#cp(*args) ⇒ Object

FileUtils.cp



1031
1032
1033
# File 'lib/pathname2.rb', line 1031

def cp(*args)
  FileUtils.cp(self, *args)
end

#cp_r(*args) ⇒ Object

FileUtils.cp_r



1036
1037
1038
# File 'lib/pathname2.rb', line 1036

def cp_r(*args)
  FileUtils.cp_r(self, *args)
end

#descendObject

Yields each component of the path, concatenating the next component on each iteration as a new Pathname object, starting with the root path.

Example:

path = Pathname.new('/usr/local/bin')

path.descend{ |name|
   puts name
}

First iteration  => '/'
Second iteration => '/usr'
Third iteration  => '/usr/local'
Fourth iteration => '/usr/local/bin'


414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/pathname2.rb', line 414

def descend
  if root?
    yield root
    return
  end

  if @win
    path = unc? ? "#{root}\\" : ""
  else
    path = absolute? ? root : ""
  end

  # Yield the root directory if an absolute path (and not Windows)
  unless @win && !unc?
    yield root if absolute?
  end

  each{ |element|
    if @win && unc?
      next if root.to_a.include?(element)
    end
    path << element << @sep
    yield self.class.new(path.chop)
  }
end

#dirname(level = 1) ⇒ Object

Similar to File.dirname, but this method allows you to specify the number of levels up you wish to refer to.

The default level is 1, i.e. it works the same as File.dirname. A level of 0 will return the original path. A level equal to or greater than the number of path elements will return the root path.

A number less than 0 will raise an ArgumentError.

Example:

path = Pathname.new('/usr/local/bin/ruby')

puts path.dirname    # => /usr/local/bin
puts path.dirname(2) # => /usr/local
puts path.dirname(3) # => /usr
puts path.dirname(9) # => /

Raises:

  • (ArgumentError)


808
809
810
811
812
813
814
# File 'lib/pathname2.rb', line 808

def dirname(level = 1)
  raise ArgumentError if level < 0
  local_path = self.dup

  level.times{ |n| local_path = File.dirname(local_path) }
  self.class.new(local_path)
end

#drive_numberObject

MS Windows only

Returns the drive number that corresponds to the root, or nil if not applicable.

Example:

Pathname.new("C:\\foo").drive_number # => 2


562
563
564
565
566
567
568
569
# File 'lib/pathname2.rb', line 562

def drive_number
  unless @win
    raise NotImplementedError, "not supported on this platform"
  end

  num = PathGetDriveNumberW(self.wincode)
  num >= 0 ? num : nil
end

#eachObject

Yields each component of the path name to a block.

Example:

Pathname.new('/usr/local/bin').each{ |element|
   puts "Element: #{element}"
}

Yields 'usr', 'local', and 'bin', in turn


351
352
353
# File 'lib/pathname2.rb', line 351

def each
  to_a.each{ |element| yield element }
end

#entriesObject

Dir.entries



912
913
914
# File 'lib/pathname2.rb', line 912

def entries
  Dir.entries(self).map{ |file| self.class.new(file) }
end

#expand_path(*args) ⇒ Object

File.expand_path



994
995
996
# File 'lib/pathname2.rb', line 994

def expand_path(*args)
  self.class.new(File.expand_path(self, *args))
end

#find(&block) ⇒ Object

Pathname#find is an iterator to traverse a directory tree in a depth first manner. It yields a Pathname for each file under the directory passed to Pathname.new.

Since it is implemented by the Find module, Find.prune can be used to control the traverse.

If self is “.”, yielded pathnames begin with a filename in the current current directory, not “.”.



857
858
859
860
861
862
863
864
# File 'lib/pathname2.rb', line 857

def find(&block)
  require "find"
  if self == "."
    Find.find(self){ |f| yield self.class.new(f.sub(%r{\A\./}, '')) }
  else
    Find.find(self){ |f| yield self.class.new(f) }
  end
end

#fnmatch(pattern, *args) ⇒ Object

File.fnmatch



949
950
951
# File 'lib/pathname2.rb', line 949

def fnmatch(pattern, *args)
  File.fnmatch(pattern, self, *args)
end

#fnmatch?(pattern, *args) ⇒ Boolean

File.fnmatch?

Returns:

  • (Boolean)


954
955
956
# File 'lib/pathname2.rb', line 954

def fnmatch?(pattern, *args)
  File.fnmatch?(pattern, self, *args)
end

#foreach(*args, &block) ⇒ Object

IO.foreach



869
870
871
# File 'lib/pathname2.rb', line 869

def foreach(*args, &block)
  IO.foreach(self, *args, &block)
end

#glob(*args) ⇒ Object

Dir.glob

:no-doc: This differs from Tanaka’s implementation in that it does a temporary chdir to the path in question, then performs the glob.



896
897
898
899
900
901
902
903
904
# File 'lib/pathname2.rb', line 896

def glob(*args)
  Dir.chdir(self){
    if block_given?
      Dir.glob(*args){ |file| yield self.class.new(file) }
    else
      Dir.glob(*args).map{ |file| self.class.new(file) }
    end
  }
end

#install(*args) ⇒ Object

FileUtils.install



1073
1074
1075
# File 'lib/pathname2.rb', line 1073

def install(*args)
  FileUtils.install(self, *args)
end

#join(*args) ⇒ Object

Joins the given pathnames onto self to create a new Pathname object.

path = Pathname.new("C:/Users")
path = path.join("foo", "Downloads") # => C:/Users/foo/Downloads


821
822
823
824
825
826
827
828
829
830
831
832
833
834
# File 'lib/pathname2.rb', line 821

def join(*args)
  args.unshift self
  result = args.pop
  result = self.class.new(result) unless result === self.class
  return result if result.absolute?

  args.reverse_each{ |path|
    path = self.class.new(path) unless path === self.class
    result = path + result
    break if result.absolute?
  }

  result
end

#lchmod(mode) ⇒ Object

File.lchmod



934
935
936
# File 'lib/pathname2.rb', line 934

def lchmod(mode)
  File.lchmod(mode, self)
end

#lchown(owner, group) ⇒ Object

File.lchown



944
945
946
# File 'lib/pathname2.rb', line 944

def lchown(owner, group)
  File.lchown(owner, group, self)
end

File.link



959
960
961
# File 'lib/pathname2.rb', line 959

def link(old)
  File.link(old, self)
end

#ln(*args) ⇒ Object

FileUtils.ln



1016
1017
1018
# File 'lib/pathname2.rb', line 1016

def ln(*args)
  FileUtils.ln(self, *args)
end

#ln_s(*args) ⇒ Object

FileUtils.ln_s



1021
1022
1023
# File 'lib/pathname2.rb', line 1021

def ln_s(*args)
  FileUtils.ln_s(self, *args)
end

#ln_sf(*args) ⇒ Object

FileUtils.ln_sf



1026
1027
1028
# File 'lib/pathname2.rb', line 1026

def ln_sf(*args)
  FileUtils.ln_sf(self, *args)
end

#long_pathObject

Windows only

Returns the long path for a long path name.

Example:

path = Pathname.new('C:\Progra~1\Java')
path.long_path # => C:\Program Files\Java.

Raises:

  • (NotImplementedError)


285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/pathname2.rb', line 285

def long_path
  raise NotImplementedError, "not supported on this platform" unless @win

  buf = FFI::MemoryPointer.new(:char, MAXPATH)
  wpath = self.wincode

  size = GetLongPathNameW(wpath, buf, buf.size)

  raise SystemCallError.new('GetShortPathName', FFI.errno) if size == 0

  self.class.new(buf.read_bytes(size * 2).delete(0.chr))
end

#mkdir(*args) ⇒ Object

Dir.mkdir



917
918
919
# File 'lib/pathname2.rb', line 917

def mkdir(*args)
  Dir.mkdir(self, *args)
end

#mkdir_p(*args) ⇒ Object Also known as: mkpath

FileUtils.mkdir_p



1009
1010
1011
# File 'lib/pathname2.rb', line 1009

def mkdir_p(*args)
  FileUtils.mkdir_p(self, *args)
end

#mv(*args) ⇒ Object

FileUtils.mv



1041
1042
1043
# File 'lib/pathname2.rb', line 1041

def mv(*args)
  FileUtils.mv(self, *args)
end

#open(*args, &block) ⇒ Object

File.open



964
965
966
# File 'lib/pathname2.rb', line 964

def open(*args, &block)
  File.open(self, *args, &block)
end

#opendir(&block) ⇒ Object

Dir.opendir



922
923
924
# File 'lib/pathname2.rb', line 922

def opendir(&block)
  Dir.open(self, &block)
end

#parentObject

Returns the parent directory of the given path.

Example:

Pathname.new('/usr/local/bin').parent # => '/usr/local'


594
595
596
597
# File 'lib/pathname2.rb', line 594

def parent
  return self if root?
  self + ".." # Use our custom '+' method
end

#pretty_print(q) ⇒ Object

A custom pretty printer



837
838
839
840
841
842
843
# File 'lib/pathname2.rb', line 837

def pretty_print(q)
  if File::ALT_SEPARATOR
    q.text(self.to_s.tr(File::SEPARATOR, File::ALT_SEPARATOR))
  else
    q.text(self.to_s)
  end
end

#pstripObject

Removes all trailing slashes, if present. Non-destructive.

Example:

path = Pathname.new('/usr/local/')
path.pstrip # => '/usr/local'


305
306
307
308
309
310
311
312
313
314
315
# File 'lib/pathname2.rb', line 305

def pstrip
  str = self.dup
  return str if str.empty?

  while ["/", "\\"].include?(str.to_s[-1].chr)
    str.strip!
    str.chop!
  end

  self.class.new(str)
end

#pstrip!Object

Performs the substitution of Pathname#pstrip in place.



319
320
321
# File 'lib/pathname2.rb', line 319

def pstrip!
  self.replace(pstrip)
end

#read(*args) ⇒ Object

IO.read



874
875
876
# File 'lib/pathname2.rb', line 874

def read(*args)
  IO.read(self, *args)
end

#readlines(*args) ⇒ Object

IO.readlines



879
880
881
# File 'lib/pathname2.rb', line 879

def readlines(*args)
  IO.readlines(self, *args)
end

#realpathObject

Returns a real (absolute) pathname of self in the actual filesystem.

Unlike most Pathname methods, this one assumes that the path actually exists on your filesystem. If it doesn’t, an error is raised. If a circular symlink is encountered a system error will be raised.

Example:

Dir.pwd                      # => /usr/local
File.exists?('foo')          # => true
Pathname.new('foo').realpath # => /usr/local/foo


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/pathname2.rb', line 180

def realpath
  File.stat(self) # Check to ensure that the path exists

  if File.symlink?(self)
    file = self.dup

    while true
      file = File.join(File.dirname(file), File.readlink(file))
      break unless File.symlink?(file)
    end

    self.class.new(file).clean
  else
    self.class.new(Dir.pwd) + self
  end
end

#relative?Boolean

Returns whether or not the path is a relative path.

Example:

Pathname.new('/usr/bin').relative? # => true
Pathname.new('usr').relative?      # => false

Returns:

  • (Boolean)


734
735
736
737
738
739
740
# File 'lib/pathname2.rb', line 734

def relative?
  if @win
    PathIsRelativeW(self.wincode)
  else
    root == "."
  end
end

#relative_path_from(base) ⇒ Object

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. For relative paths, this method uses an imaginary, common parent path.

This method does not access the filesystem. It assumes no symlinks. You should only compare directories against directories, or files against files, or you may get unexpected results.

Raises an ArgumentError if it cannot find a relative path.

Examples:

path = Pathname.new('/usr/local/bin')
path.relative_path_from('/usr/bin') # => "../local/bin"

path = Pathname.new("C:\\WINNT\\Fonts")
path.relative_path_from("C:\\Program Files") # => "..\\WINNT\\Fonts"


618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/pathname2.rb', line 618

def relative_path_from(base)
  base = self.class.new(base) unless base.kind_of?(Pathname)

  if self.absolute? != base.absolute?
    raise ArgumentError, "relative path between absolute and relative path"
  end

  return self.class.new(".") if self == base
  return self if base == "."

  # Because of the way the Windows version handles Pathname#clean, we need
  # a little extra help here.
  if @win
    if root != base.root
      msg = 'cannot determine relative paths from different root paths'
      raise ArgumentError, msg
    end
    if base == '..' && (self != '..' || self != '.')
      raise ArgumentError, "base directory may not contain '..'"
    end
  end

  dest_arr = self.clean.to_a
  base_arr = base.clean.to_a
  dest_arr.delete('.')
  base_arr.delete('.')

  # diff_arr = dest_arr - base_arr

  while !base_arr.empty? && !dest_arr.empty? && base_arr[0] == dest_arr[0]
    base_arr.shift
    dest_arr.shift
  end

  if base_arr.include?("..")
    raise ArgumentError, "base directory may not contain '..'"
  end

  base_arr.fill("..")
  rel_path = base_arr + dest_arr

  if rel_path.empty?
    self.class.new(".")
  else
    self.class.new(rel_path.join(@sep))
  end
end

#remove_dir(*args) ⇒ Object

FileUtils.remove_dir



1098
1099
1100
# File 'lib/pathname2.rb', line 1098

def remove_dir(*args)
  FileUtils.remove_dir(self, *args)
end

#remove_file(*args) ⇒ Object

FileUtils.remove_file



1103
1104
1105
# File 'lib/pathname2.rb', line 1103

def remove_file(*args)
  FileUtils.remove_dir(self, *args)
end

#rename(name) ⇒ Object

File.rename



969
970
971
# File 'lib/pathname2.rb', line 969

def rename(name)
  File.rename(self, name)
end

#rm(*args) ⇒ Object Also known as: remove

FileUtils.rm



1046
1047
1048
# File 'lib/pathname2.rb', line 1046

def rm(*args)
  FileUtils.rm(self, *args)
end

#rm_f(*args) ⇒ Object

FileUtils.rm_f



1053
1054
1055
# File 'lib/pathname2.rb', line 1053

def rm_f(*args)
  FileUtils.rm_f(self, *args)
end

#rm_r(*args) ⇒ Object

FileUtils.rm_r



1058
1059
1060
# File 'lib/pathname2.rb', line 1058

def rm_r(*args)
  FileUtils.rm_r(self, *args)
end

#rm_rf(*args) ⇒ Object

FileUtils.rm_rf



1063
1064
1065
# File 'lib/pathname2.rb', line 1063

def rm_rf(*args)
  FileUtils.rm_rf(self, *args)
end

#rmtree(*args) ⇒ Object

FileUtils.rmtree



1068
1069
1070
# File 'lib/pathname2.rb', line 1068

def rmtree(*args)
  FileUtils.rmtree(self, *args)
end

#rootObject

Returns the root directory of the path, or ‘.’ if there is no root directory.

On Unix, this means the ‘/’ character. On Windows, this can refer to the drive letter, or the server and share path if the path is a UNC path.

Examples:

Pathname.new('/usr/local').root       # => '/'
Pathname.new('lib').root              # => '.'

On MS Windows:

Pathname.new('C:\WINNT').root         # => 'C:'
Pathname.new('\\some\share\foo').root # => '\\some\share'


508
509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'lib/pathname2.rb', line 508

def root
  dir = "."

  if @win
    wpath = FFI::MemoryPointer.from_string(self.wincode)
    if PathStripToRootW(wpath)
      dir = wpath.read_string(wpath.size).split("\000\000").first.tr(0.chr, '')
    end
  else
    dir = "/" if self =~ /^\//
  end

  self.class.new(dir)
end

#root?Boolean

Returns whether or not the path consists only of a root directory.

Examples:

Pathname.new('/').root?    # => true
Pathname.new('/foo').root? # => false

Returns:

  • (Boolean)


530
531
532
533
534
535
536
# File 'lib/pathname2.rb', line 530

def root?
  if @win
    PathIsRootW(self.wincode)
  else
    self == root
  end
end

#short_pathObject

Windows only

Returns the short path for a long path name.

Example:

path = Pathname.new('C:\Program Files\Java')
path.short_path # => C:\Progra~1\Java.

Raises:

  • (NotImplementedError)


263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/pathname2.rb', line 263

def short_path
  raise NotImplementedError, "not supported on this platform" unless @win

  buf = FFI::MemoryPointer.new(:char, MAXPATH)
  wpath = self.wincode

  size = GetShortPathNameW(wpath, buf, buf.size)

  raise SystemCallError.new('GetShortPathName', FFI.errno) if size == 0

  self.class.new(buf.read_bytes(size * 2).delete(0.chr))
end

File.symlink



974
975
976
# File 'lib/pathname2.rb', line 974

def symlink(old)
  File.symlink(old, self)
end

#sysopen(*args) ⇒ Object

IO.sysopen



884
885
886
# File 'lib/pathname2.rb', line 884

def sysopen(*args)
  IO.sysopen(self, *args)
end

#to_aObject

Splits a pathname into strings based on the path separator.

Examples:

Pathname.new('/usr/local/bin').to_a # => ['usr', 'local', 'bin']
Pathname.new('C:\WINNT\Fonts').to_a # => ['C:', 'WINNT', 'Fonts']


330
331
332
333
334
335
336
337
338
339
# File 'lib/pathname2.rb', line 330

def to_a
  # Split string by path separator
  if @win
    array = tr(File::SEPARATOR, File::ALT_SEPARATOR).split(@sep)
  else
    array = split(@sep)
  end
  array.delete("")    # Remove empty elements
  array
end

#touch(*args) ⇒ Object

FileUtils.touch



1078
1079
1080
# File 'lib/pathname2.rb', line 1078

def touch(*args)
  FileUtils.touch(*args)
end

#truncate(length) ⇒ Object

File.truncate



979
980
981
# File 'lib/pathname2.rb', line 979

def truncate(length)
  File.truncate(self, length)
end

#unc?Boolean

MS Windows only

Determines if the string is a valid Universal Naming Convention (UNC) for a server and share path.

Examples:

Pathname.new("\\\\foo\\bar").unc?     # => true
Pathname.new('C:\Program Files').unc? # => false

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


548
549
550
551
# File 'lib/pathname2.rb', line 548

def unc?
  raise NotImplementedError, "not supported on this platform" unless @win
  PathIsUNCW(self.wincode)
end

#undecorateObject

Windows only

Removes the decoration from a path string. Non-destructive.

Example:

path = Pathname.new(‘C:PathFile.txt’) path.undecorate # => C:PathFile.txt.



234
235
236
237
238
239
240
241
242
243
244
# File 'lib/pathname2.rb', line 234

def undecorate
  unless @win
    raise NotImplementedError, "not supported on this platform"
  end

  wpath = FFI::MemoryPointer.from_string(self.wincode)

  PathUndecorateW(wpath)

  self.class.new(wpath.read_string(wpath.size).split("\000\000").first.tr(0.chr, ''))
end

#undecorate!Object

Windows only

Performs the substitution of Pathname#undecorate in place.



250
251
252
# File 'lib/pathname2.rb', line 250

def undecorate!
  self.replace(undecorate)
end

#uptodate?(*args) ⇒ Boolean

FileUtils.uptodate?

Returns:

  • (Boolean)


1088
1089
1090
# File 'lib/pathname2.rb', line 1088

def uptodate?(*args)
  FileUtils.uptodate(self, *args)
end

#utime(atime, mtime) ⇒ Object

File.utime



984
985
986
# File 'lib/pathname2.rb', line 984

def utime(atime, mtime)
  File.utime(atime, mtime, self)
end