pathname2 1.8.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/{CHANGES → CHANGES.md} +41 -29
  4. data/Gemfile +2 -0
  5. data/{MANIFEST → MANIFEST.md} +6 -5
  6. data/README.md +104 -0
  7. data/Rakefile +227 -222
  8. data/benchmarks/bench_pathname2.rb +127 -0
  9. data/examples/{example_pathname.rb → example_pathname2.rb} +7 -7
  10. data/lib/pathname2.rb +169 -171
  11. data/pathname2.gemspec +15 -13
  12. data/test/{test_pathname.rb → test_pathname2.rb} +67 -63
  13. data/test/test_version.rb +3 -3
  14. data/test/windows/test_append.rb +7 -7
  15. data/test/windows/test_aref.rb +3 -3
  16. data/test/windows/test_ascend.rb +5 -5
  17. data/test/windows/test_children.rb +7 -7
  18. data/test/windows/test_clean.rb +17 -17
  19. data/test/windows/test_clean_bang.rb +17 -17
  20. data/test/windows/test_constructor.rb +12 -12
  21. data/test/windows/test_descend.rb +5 -5
  22. data/test/windows/test_drive_number.rb +13 -13
  23. data/test/windows/test_each.rb +3 -3
  24. data/test/windows/test_facade.rb +6 -6
  25. data/test/windows/test_is_absolute.rb +8 -8
  26. data/test/windows/test_is_relative.rb +7 -7
  27. data/test/windows/test_is_root.rb +8 -8
  28. data/test/windows/test_is_unc.rb +18 -18
  29. data/test/windows/test_join.rb +8 -8
  30. data/test/windows/test_long_path.rb +6 -6
  31. data/test/windows/test_misc.rb +7 -7
  32. data/test/windows/test_parent.rb +9 -9
  33. data/test/windows/test_pstrip.rb +9 -9
  34. data/test/windows/test_pstrip_bang.rb +10 -10
  35. data/test/windows/test_realpath.rb +5 -5
  36. data/test/windows/test_relative_path_from.rb +4 -4
  37. data/test/windows/test_root.rb +14 -14
  38. data/test/windows/test_short_path.rb +6 -6
  39. data/test/windows/test_to_a.rb +12 -12
  40. data/test/windows/test_undecorate.rb +12 -12
  41. data/test/windows/test_undecorate_bang.rb +13 -13
  42. data.tar.gz.sig +0 -0
  43. metadata +62 -57
  44. metadata.gz.sig +0 -0
  45. data/README +0 -97
  46. data/benchmarks/bench_pathname.rb +0 -127
data/lib/pathname2.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # == Synopsis
2
2
  #
3
- # Pathname represents a path name on a filesystem. A Pathname can be
4
- # relative or absolute. It does not matter whether the path exists or not.
3
+ # Pathname2 represents a path name on a filesystem. A path name can be
4
+ # relative or absolute. It does not matter whether the path exists or not.
5
5
  #
6
6
  # All functionality from File, FileTest, and Dir is included, using a facade
7
7
  # pattern.
@@ -14,15 +14,15 @@
14
14
  # require "pathname2"
15
15
  #
16
16
  # # Unix
17
- # path1 = Pathname.new("/foo/bar/baz")
18
- # path2 = Pathname.new("../zap")
17
+ # path1 = Pathname2.new("/foo/bar/baz")
18
+ # path2 = Pathname2.new("../zap")
19
19
  #
20
20
  # path1 + path2 # "/foo/bar/zap"
21
21
  # path1.dirname # "/foo/bar"
22
22
  #
23
23
  # # Windows
24
- # path1 = Pathname.new("C:\\foo\\bar\\baz")
25
- # path2 = Pathname.new("..\\zap")
24
+ # path1 = Pathname2.new("C:\\foo\\bar\\baz")
25
+ # path2 = Pathname2.new("..\\zap")
26
26
  #
27
27
  # path1 + path2 # "C:\\foo\\bar\\zap"
28
28
  # path1.exists? # Does the path exist?
@@ -37,44 +37,41 @@ if File::ALT_SEPARATOR
37
37
  # Convenience method for converting strings to UTF-16LE for wide character
38
38
  # functions that require it.
39
39
  def wincode
40
- if self.encoding.name != 'UTF-16LE'
41
- temp = self.dup
40
+ if encoding.name != 'UTF-16LE'
41
+ temp = dup
42
42
  (temp.tr(File::SEPARATOR, File::ALT_SEPARATOR) << 0.chr).encode('UTF-16LE')
43
43
  end
44
44
  end
45
45
  end
46
46
  end
47
47
 
48
- # You're mine now.
49
- Object.send(:remove_const, :Pathname) if defined?(Pathname)
50
-
51
- class Pathname < String
48
+ class Pathname2 < String
52
49
  class Error < StandardError; end
53
50
  extend Facade
54
51
 
55
52
  undef_method :pretty_print
56
53
 
57
- facade File, File.methods(false).map{ |m| m.to_sym } - [
58
- :chmod, :lchmod, :chown, :lchown, :dirname, :fnmatch, :fnmatch?,
59
- :link, :open, :realpath, :rename, :symlink, :truncate, :utime,
60
- :basename, :expand_path, :join
54
+ facade File, File.methods(false).map(&:to_sym) - %i[
55
+ chmod lchmod chown lchown dirname fnmatch fnmatch?
56
+ link open realpath rename symlink truncate utime
57
+ basename expand_path join
61
58
  ]
62
59
 
63
- facade Dir, Dir.methods(false).map{ |m| m.to_sym } - [
64
- :chdir, :entries, :glob, :foreach, :mkdir, :open, :children
60
+ facade Dir, Dir.methods(false).map(&:to_sym) - %i[
61
+ chdir entries glob foreach mkdir open children
65
62
  ]
66
63
 
67
- private
64
+ alias _plus_ + # Used to prevent infinite loops in some cases
68
65
 
69
- alias :_plus_ :+ # Used to prevent infinite loops in some cases
66
+ protected :_plus_
70
67
 
71
68
  if File::ALT_SEPARATOR
72
69
  extend FFI::Library
73
70
  ffi_lib :shlwapi
74
71
 
75
- attach_function :PathAppendW, [:pointer, :pointer], :bool
76
- attach_function :PathCanonicalizeW, [:pointer, :buffer_in], :bool
77
- attach_function :PathCreateFromUrlW, [:buffer_in, :pointer, :pointer, :ulong], :long
72
+ attach_function :PathAppendW, %i[pointer pointer], :bool
73
+ attach_function :PathCanonicalizeW, %i[pointer buffer_in], :bool
74
+ attach_function :PathCreateFromUrlW, %i[buffer_in pointer pointer ulong], :long
78
75
  attach_function :PathGetDriveNumberW, [:buffer_in], :int
79
76
  attach_function :PathIsRelativeW, [:buffer_in], :bool
80
77
  attach_function :PathIsRootW, [:buffer_in], :bool
@@ -86,21 +83,26 @@ class Pathname < String
86
83
 
87
84
  ffi_lib :kernel32
88
85
 
89
- attach_function :GetLongPathNameW, [:buffer_in, :buffer_out, :ulong], :ulong
90
- attach_function :GetShortPathNameW, [:buffer_in, :pointer, :ulong], :ulong
86
+ attach_function :GetLongPathNameW, %i[buffer_in buffer_out ulong], :ulong
87
+ attach_function :GetShortPathNameW, %i[buffer_in pointer ulong], :ulong
88
+
89
+ private_class_method :PathAppendW, :PathCanonicalizeW, :PathCreateFromUrlW
90
+ private_class_method :PathGetDriveNumberW, :PathIsRelativeW, :PathIsRelativeW
91
+ private_class_method :PathIsRootW, :PathIsUNCW, :PathIsURLW, :PathRemoveBackslashW
92
+ private_class_method :PathStripToRootW, :PathUndecorateW, :GetLongPathNameW, :GetShortPathNameW
91
93
  end
92
94
 
93
95
  public
94
96
 
95
97
  # The version of the pathname2 library
96
- VERSION = '1.8.3'.freeze
98
+ VERSION = '2.0.0'.freeze
97
99
 
98
100
  # The maximum length of a path
99
101
  MAXPATH = 1024 unless defined? MAXPATH # Yes, I willfully violate POSIX
100
102
 
101
103
  # Returns the expanded path of the current working directory.
102
104
  #
103
- # Synonym for Pathname.new(Dir.pwd).
105
+ # Synonym for Pathname2.new(Dir.pwd).
104
106
  #
105
107
  def self.pwd
106
108
  new(Dir.pwd)
@@ -110,25 +112,25 @@ class Pathname < String
110
112
  alias getwd pwd
111
113
  end
112
114
 
113
- # Creates and returns a new Pathname object.
115
+ # Creates and returns a new Pathname2 object.
114
116
  #
115
117
  # On platforms that define File::ALT_SEPARATOR, all forward slashes are
116
118
  # replaced with the value of File::ALT_SEPARATOR. On MS Windows, for
117
119
  # example, all forward slashes are replaced with backslashes.
118
120
  #
119
- # File URL's will be converted to Pathname objects, e.g. the file URL
121
+ # File URL's will be converted to Pathname2 objects, e.g. the file URL
120
122
  # "file:///C:/Documents%20and%20Settings" will become 'C:\Documents and Settings'.
121
123
  #
122
124
  # Examples:
123
125
  #
124
- # Pathname.new("/foo/bar/baz")
125
- # Pathname.new("foo")
126
- # Pathname.new("file:///foo/bar/baz")
127
- # Pathname.new("C:\\Documents and Settings\\snoopy")
126
+ # Pathname2.new("/foo/bar/baz")
127
+ # Pathname2.new("foo")
128
+ # Pathname2.new("file:///foo/bar/baz")
129
+ # Pathname2.new("C:\\Documents and Settings\\snoopy")
128
130
  #
129
131
  def initialize(path)
130
132
  if path.length > MAXPATH
131
- msg = "string too long. maximum string length is " + MAXPATH.to_s
133
+ msg = 'string too long. maximum string length is ' + MAXPATH.to_s
132
134
  raise ArgumentError, msg
133
135
  end
134
136
 
@@ -154,8 +156,8 @@ class Pathname < String
154
156
  end
155
157
  else
156
158
  if path.index('file:///', 0)
157
- require 'uri'
158
- path = URI::Parser.new.unescape(path)[7..-1]
159
+ require 'addressable'
160
+ path = Addressable::URI.unescape(path)[7..-1]
159
161
  end
160
162
  end
161
163
 
@@ -167,7 +169,7 @@ class Pathname < String
167
169
 
168
170
  # Returns a real (absolute) pathname of +self+ in the actual filesystem.
169
171
  #
170
- # Unlike most Pathname methods, this one assumes that the path actually
172
+ # Unlike most Pathname2 methods, this one assumes that the path actually
171
173
  # exists on your filesystem. If it doesn't, an error is raised. If a
172
174
  # circular symlink is encountered a system error will be raised.
173
175
  #
@@ -175,15 +177,15 @@ class Pathname < String
175
177
  #
176
178
  # Dir.pwd # => /usr/local
177
179
  # File.exists?('foo') # => true
178
- # Pathname.new('foo').realpath # => /usr/local/foo
180
+ # Pathname2.new('foo').realpath # => /usr/local/foo
179
181
  #
180
182
  def realpath
181
183
  File.stat(self) # Check to ensure that the path exists
182
184
 
183
185
  if File.symlink?(self)
184
- file = self.dup
186
+ file = dup
185
187
 
186
- while true
188
+ loop do
187
189
  file = File.join(File.dirname(file), File.readlink(file))
188
190
  break unless File.symlink?(file)
189
191
  end
@@ -195,7 +197,7 @@ class Pathname < String
195
197
  end
196
198
 
197
199
  # Returns the children of the directory, files and subdirectories, as an
198
- # array of Pathname objects. If you set +with_directory+ to +false+, then
200
+ # array of Pathname2 objects. If you set +with_directory+ to +false+, then
199
201
  # the returned pathnames will contain the filename only.
200
202
  #
201
203
  # Note that the result never contain the entries '.' and '..' in the
@@ -204,21 +206,21 @@ class Pathname < String
204
206
  #
205
207
  # Example:
206
208
  #
207
- # path = Pathname.new('/usr/bin')
209
+ # path = Pathname2.new('/usr/bin')
208
210
  # path.children # => ['/usr/bin/ruby', '/usr/bin/perl', ...]
209
211
  # path.children(false) # => ['ruby', 'perl', ...]
210
212
  #
211
213
  def children(with_directory = true)
212
214
  with_directory = false if self == '.'
213
215
  result = []
214
- Dir.foreach(self) { |file|
216
+ Dir.foreach(self) do |file|
215
217
  next if file == '.' || file == '..'
216
218
  if with_directory
217
219
  result << self.class.new(File.join(self, file))
218
220
  else
219
221
  result << self.class.new(file)
220
222
  end
221
- }
223
+ end
222
224
  result
223
225
  end
224
226
 
@@ -228,15 +230,15 @@ class Pathname < String
228
230
  #
229
231
  # Example:
230
232
  #
231
- # path = Pathname.new('C:\Path\File[5].txt')
233
+ # path = Pathname2.new('C:\Path\File[5].txt')
232
234
  # path.undecorate # => C:\Path\File.txt.
233
235
  #
234
236
  def undecorate
235
237
  unless @win
236
- raise NotImplementedError, "not supported on this platform"
238
+ raise NotImplementedError, 'not supported on this platform'
237
239
  end
238
240
 
239
- wpath = FFI::MemoryPointer.from_string(self.wincode)
241
+ wpath = FFI::MemoryPointer.from_string(wincode)
240
242
 
241
243
  PathUndecorateW(wpath)
242
244
 
@@ -245,10 +247,10 @@ class Pathname < String
245
247
 
246
248
  # Windows only
247
249
  #
248
- # Performs the substitution of Pathname#undecorate in place.
250
+ # Performs the substitution of Pathname2#undecorate in place.
249
251
  #
250
252
  def undecorate!
251
- self.replace(undecorate)
253
+ replace(undecorate)
252
254
  end
253
255
 
254
256
  # Windows only
@@ -257,14 +259,14 @@ class Pathname < String
257
259
  #
258
260
  # Example:
259
261
  #
260
- # path = Pathname.new('C:\Program Files\Java')
262
+ # path = Pathname2.new('C:\Program Files\Java')
261
263
  # path.short_path # => C:\Progra~1\Java.
262
264
  #
263
265
  def short_path
264
- raise NotImplementedError, "not supported on this platform" unless @win
266
+ raise NotImplementedError, 'not supported on this platform' unless @win
265
267
 
266
268
  buf = FFI::MemoryPointer.new(:char, MAXPATH)
267
- wpath = self.wincode
269
+ wpath = wincode
268
270
 
269
271
  size = GetShortPathNameW(wpath, buf, buf.size)
270
272
 
@@ -279,14 +281,14 @@ class Pathname < String
279
281
  #
280
282
  # Example:
281
283
  #
282
- # path = Pathname.new('C:\Progra~1\Java')
284
+ # path = Pathname2.new('C:\Progra~1\Java')
283
285
  # path.long_path # => C:\Program Files\Java.
284
286
  #
285
287
  def long_path
286
- raise NotImplementedError, "not supported on this platform" unless @win
288
+ raise NotImplementedError, 'not supported on this platform' unless @win
287
289
 
288
290
  buf = FFI::MemoryPointer.new(:char, MAXPATH)
289
- wpath = self.wincode
291
+ wpath = wincode
290
292
 
291
293
  size = GetLongPathNameW(wpath, buf, buf.size)
292
294
 
@@ -299,14 +301,14 @@ class Pathname < String
299
301
  #
300
302
  # Example:
301
303
  #
302
- # path = Pathname.new('/usr/local/')
304
+ # path = Pathname2.new('/usr/local/')
303
305
  # path.pstrip # => '/usr/local'
304
306
  #
305
307
  def pstrip
306
- str = self.dup
308
+ str = dup
307
309
  return str if str.empty?
308
310
 
309
- while ["/", "\\"].include?(str.to_s[-1].chr)
311
+ while [File::SEPARATOR, File::ALT_SEPARATOR].include?(str.to_s[-1].chr)
310
312
  str.strip!
311
313
  str.chop!
312
314
  end
@@ -314,18 +316,18 @@ class Pathname < String
314
316
  self.class.new(str)
315
317
  end
316
318
 
317
- # Performs the substitution of Pathname#pstrip in place.
319
+ # Performs the substitution of Pathname2#pstrip in place.
318
320
  #
319
321
  def pstrip!
320
- self.replace(pstrip)
322
+ replace(pstrip)
321
323
  end
322
324
 
323
325
  # Splits a pathname into strings based on the path separator.
324
326
  #
325
327
  # Examples:
326
328
  #
327
- # Pathname.new('/usr/local/bin').to_a # => ['usr', 'local', 'bin']
328
- # Pathname.new('C:\WINNT\Fonts').to_a # => ['C:', 'WINNT', 'Fonts']
329
+ # Pathname2.new('/usr/local/bin').to_a # => ['usr', 'local', 'bin']
330
+ # Pathname2.new('C:\WINNT\Fonts').to_a # => ['C:', 'WINNT', 'Fonts']
329
331
  #
330
332
  def to_a
331
333
  # Split string by path separator
@@ -334,7 +336,7 @@ class Pathname < String
334
336
  else
335
337
  array = split(@sep)
336
338
  end
337
- array.delete("") # Remove empty elements
339
+ array.delete('') # Remove empty elements
338
340
  array
339
341
  end
340
342
 
@@ -342,7 +344,7 @@ class Pathname < String
342
344
  #
343
345
  # Example:
344
346
  #
345
- # Pathname.new('/usr/local/bin').each{ |element|
347
+ # Pathname2.new('/usr/local/bin').each{ |element|
346
348
  # puts "Element: #{element}"
347
349
  # }
348
350
  #
@@ -360,13 +362,13 @@ class Pathname < String
360
362
  #
361
363
  # Examples:
362
364
  #
363
- # path = Pathname.new('/home/john/source/ruby')
365
+ # path = Pathname2.new('/home/john/source/ruby')
364
366
  # path[0] # => 'home'
365
367
  # path[1] # => 'john'
366
368
  # path[0, 3] # => '/home/john/source'
367
369
  # path[0..1] # => '/home/john'
368
370
  #
369
- # path = Pathname.new('C:/Documents and Settings/John/Source/Ruby')
371
+ # path = Pathname2.new('C:/Documents and Settings/John/Source/Ruby')
370
372
  # path[0] # => 'C:\'
371
373
  # path[1] # => 'Documents and Settings'
372
374
  # path[0, 3] # => 'C:\Documents and Settings\John'
@@ -385,22 +387,22 @@ class Pathname < String
385
387
  end
386
388
  path = File.join(to_a[index])
387
389
  else
388
- raise TypeError, "Only Numerics and Ranges allowed as first argument"
390
+ raise TypeError, 'Only Numerics and Ranges allowed as first argument'
389
391
  end
390
392
 
391
393
  if path && @win
392
- path = path.tr("/", "\\")
394
+ path = path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
393
395
  end
394
396
 
395
397
  path
396
398
  end
397
399
 
398
400
  # Yields each component of the path, concatenating the next component on
399
- # each iteration as a new Pathname object, starting with the root path.
401
+ # each iteration as a new Pathname2 object, starting with the root path.
400
402
  #
401
403
  # Example:
402
404
  #
403
- # path = Pathname.new('/usr/local/bin')
405
+ # path = Pathname2.new('/usr/local/bin')
404
406
  #
405
407
  # path.descend{ |name|
406
408
  # puts name
@@ -418,9 +420,9 @@ class Pathname < String
418
420
  end
419
421
 
420
422
  if @win
421
- path = unc? ? "#{root}\\" : ""
423
+ path = unc? ? "#{root}\\" : ''
422
424
  else
423
- path = absolute? ? root : ""
425
+ path = absolute? ? root : ''
424
426
  end
425
427
 
426
428
  # Yield the root directory if an absolute path (and not Windows)
@@ -428,21 +430,21 @@ class Pathname < String
428
430
  yield root if absolute?
429
431
  end
430
432
 
431
- each{ |element|
433
+ each do |element|
432
434
  if @win && unc?
433
435
  next if root.to_a.include?(element)
434
436
  end
435
437
  path << element << @sep
436
438
  yield self.class.new(path.chop)
437
- }
439
+ end
438
440
  end
439
441
 
440
442
  # Yields the path, minus one component on each iteration, as a new
441
- # Pathname object, ending with the root path.
443
+ # Pathname2 object, ending with the root path.
442
444
  #
443
445
  # Example:
444
446
  #
445
- # path = Pathname.new('/usr/local/bin')
447
+ # path = Pathname2.new('/usr/local/bin')
446
448
  #
447
449
  # path.ascend{ |name|
448
450
  # puts name
@@ -497,24 +499,24 @@ class Pathname < String
497
499
  #
498
500
  # Examples:
499
501
  #
500
- # Pathname.new('/usr/local').root # => '/'
501
- # Pathname.new('lib').root # => '.'
502
+ # Pathname2.new('/usr/local').root # => '/'
503
+ # Pathname2.new('lib').root # => '.'
502
504
  #
503
505
  # On MS Windows:
504
506
  #
505
- # Pathname.new('C:\WINNT').root # => 'C:'
506
- # Pathname.new('\\some\share\foo').root # => '\\some\share'
507
+ # Pathname2.new('C:\WINNT').root # => 'C:'
508
+ # Pathname2.new('\\some\share\foo').root # => '\\some\share'
507
509
  #
508
510
  def root
509
- dir = "."
511
+ dir = '.'
510
512
 
511
513
  if @win
512
- wpath = FFI::MemoryPointer.from_string(self.wincode)
514
+ wpath = FFI::MemoryPointer.from_string(wincode)
513
515
  if PathStripToRootW(wpath)
514
516
  dir = wpath.read_string(wpath.size).split("\000\000").first.tr(0.chr, '')
515
517
  end
516
518
  else
517
- dir = "/" if self =~ /^\//
519
+ dir = '/' if self =~ /^\//
518
520
  end
519
521
 
520
522
  self.class.new(dir)
@@ -524,12 +526,12 @@ class Pathname < String
524
526
  #
525
527
  # Examples:
526
528
  #
527
- # Pathname.new('/').root? # => true
528
- # Pathname.new('/foo').root? # => false
529
+ # Pathname2.new('/').root? # => true
530
+ # Pathname2.new('/foo').root? # => false
529
531
  #
530
532
  def root?
531
533
  if @win
532
- PathIsRootW(self.wincode)
534
+ PathIsRootW(wincode)
533
535
  else
534
536
  self == root
535
537
  end
@@ -542,12 +544,12 @@ class Pathname < String
542
544
  #
543
545
  # Examples:
544
546
  #
545
- # Pathname.new("\\\\foo\\bar").unc? # => true
546
- # Pathname.new('C:\Program Files').unc? # => false
547
+ # Pathname2.new("\\\\foo\\bar").unc? # => true
548
+ # Pathname2.new('C:\Program Files').unc? # => false
547
549
  #
548
550
  def unc?
549
- raise NotImplementedError, "not supported on this platform" unless @win
550
- PathIsUNCW(self.wincode)
551
+ raise NotImplementedError, 'not supported on this platform' unless @win
552
+ PathIsUNCW(wincode)
551
553
  end
552
554
 
553
555
  # MS Windows only
@@ -557,31 +559,32 @@ class Pathname < String
557
559
  #
558
560
  # Example:
559
561
  #
560
- # Pathname.new("C:\\foo").drive_number # => 2
562
+ # Pathname2.new("C:\\foo").drive_number # => 2
561
563
  #
562
564
  def drive_number
563
565
  unless @win
564
- raise NotImplementedError, "not supported on this platform"
566
+ raise NotImplementedError, 'not supported on this platform'
565
567
  end
566
568
 
567
- num = PathGetDriveNumberW(self.wincode)
569
+ num = PathGetDriveNumberW(wincode)
568
570
  num >= 0 ? num : nil
569
571
  end
570
572
 
571
- # Compares two Pathname objects. Note that Pathnames may only be compared
572
- # against other Pathnames, not strings. Otherwise nil is returned.
573
+ # Compares two Pathname2 objects. Note that Pathname2 objects may only be
574
+ # compared against other Pathname2 objects, not strings, otherwise nil is
575
+ # returned.
573
576
  #
574
577
  # Example:
575
578
  #
576
- # path1 = Pathname.new('/usr/local')
577
- # path2 = Pathname.new('/usr/local')
578
- # path3 = Pathname.new('/usr/local/bin')
579
+ # path1 = Pathname2.new('/usr/local')
580
+ # path2 = Pathname2.new('/usr/local')
581
+ # path3 = Pathname2.new('/usr/local/bin')
579
582
  #
580
583
  # path1 <=> path2 # => 0
581
584
  # path1 <=> path3 # => -1
582
585
  #
583
586
  def <=>(string)
584
- return nil unless string.kind_of?(Pathname)
587
+ return nil unless string.is_a?(Pathname2)
585
588
  super
586
589
  end
587
590
 
@@ -589,11 +592,11 @@ class Pathname < String
589
592
  #
590
593
  # Example:
591
594
  #
592
- # Pathname.new('/usr/local/bin').parent # => '/usr/local'
595
+ # Pathname2.new('/usr/local/bin').parent # => '/usr/local'
593
596
  #
594
597
  def parent
595
598
  return self if root?
596
- self + ".." # Use our custom '+' method
599
+ self + '..' # Use our custom '+' method
597
600
  end
598
601
 
599
602
  # Returns a relative path from the argument to the receiver. If +self+
@@ -609,23 +612,23 @@ class Pathname < String
609
612
  #
610
613
  # Examples:
611
614
  #
612
- # path = Pathname.new('/usr/local/bin')
615
+ # path = Pathname2.new('/usr/local/bin')
613
616
  # path.relative_path_from('/usr/bin') # => "../local/bin"
614
617
  #
615
- # path = Pathname.new("C:\\WINNT\\Fonts")
618
+ # path = Pathname2.new("C:\\WINNT\\Fonts")
616
619
  # path.relative_path_from("C:\\Program Files") # => "..\\WINNT\\Fonts"
617
620
  #
618
621
  def relative_path_from(base)
619
- base = self.class.new(base) unless base.kind_of?(Pathname)
622
+ base = self.class.new(base) unless base.is_a?(Pathname2)
620
623
 
621
- if self.absolute? != base.absolute?
622
- raise ArgumentError, "relative path between absolute and relative path"
624
+ if absolute? != base.absolute?
625
+ raise ArgumentError, 'relative path between absolute and relative path'
623
626
  end
624
627
 
625
- return self.class.new(".") if self == base
626
- return self if base == "."
628
+ return self.class.new('.') if self == base
629
+ return self if base == '.'
627
630
 
628
- # Because of the way the Windows version handles Pathname#clean, we need
631
+ # Because of the way the Windows version handles Pathname2#clean, we need
629
632
  # a little extra help here.
630
633
  if @win
631
634
  if root != base.root
@@ -637,7 +640,7 @@ class Pathname < String
637
640
  end
638
641
  end
639
642
 
640
- dest_arr = self.clean.to_a
643
+ dest_arr = clean.to_a
641
644
  base_arr = base.clean.to_a
642
645
  dest_arr.delete('.')
643
646
  base_arr.delete('.')
@@ -649,22 +652,22 @@ class Pathname < String
649
652
  dest_arr.shift
650
653
  end
651
654
 
652
- if base_arr.include?("..")
655
+ if base_arr.include?('..')
653
656
  raise ArgumentError, "base directory may not contain '..'"
654
657
  end
655
658
 
656
- base_arr.fill("..")
659
+ base_arr.fill('..')
657
660
  rel_path = base_arr + dest_arr
658
661
 
659
662
  if rel_path.empty?
660
- self.class.new(".")
663
+ self.class.new('.')
661
664
  else
662
665
  self.class.new(rel_path.join(@sep))
663
666
  end
664
667
  end
665
668
 
666
- # Adds two Pathname objects together, or a Pathname and a String. It
667
- # also automatically cleans the Pathname.
669
+ # Adds two Pathname2 objects together, or a Pathname2 and a String. It
670
+ # also automatically cleans the Pathname2.
668
671
  #
669
672
  # Adding a root path to an existing path merely replaces the current
670
673
  # path. Adding '.' to an existing path does nothing.
@@ -676,18 +679,18 @@ class Pathname < String
676
679
  # path1 + path2 # '/foo/baz'
677
680
  #
678
681
  def +(string)
679
- unless string.kind_of?(Pathname)
682
+ unless string.is_a?(Pathname2)
680
683
  string = self.class.new(string)
681
684
  end
682
685
 
683
686
  # Any path plus "." is the same directory
684
- return self if string == "."
685
- return string if self == "."
687
+ return self if string == '.'
688
+ return string if self == '.'
686
689
 
687
690
  # Use the builtin PathAppend() function if on Windows - much easier
688
691
  if @win
689
692
  path = FFI::MemoryPointer.new(:char, MAXPATH)
690
- path.write_string(self.dup.wincode)
693
+ path.write_string(dup.wincode)
691
694
  more = FFI::MemoryPointer.from_string(string.wincode)
692
695
 
693
696
  PathAppendW(path, more)
@@ -711,14 +714,14 @@ class Pathname < String
711
714
  self.class.new(new_string).clean
712
715
  end
713
716
 
714
- alias :/ :+
717
+ alias / +
715
718
 
716
719
  # Returns whether or not the path is an absolute path.
717
720
  #
718
721
  # Example:
719
722
  #
720
- # Pathname.new('/usr/bin').absolute? # => true
721
- # Pathname.new('usr').absolute? # => false
723
+ # Pathname2.new('/usr/bin').absolute? # => true
724
+ # Pathname2.new('usr').absolute? # => false
722
725
  #
723
726
  def absolute?
724
727
  !relative?
@@ -728,14 +731,14 @@ class Pathname < String
728
731
  #
729
732
  # Example:
730
733
  #
731
- # Pathname.new('/usr/bin').relative? # => true
732
- # Pathname.new('usr').relative? # => false
734
+ # Pathname2.new('/usr/bin').relative? # => true
735
+ # Pathname2.new('usr').relative? # => false
733
736
  #
734
737
  def relative?
735
738
  if @win
736
- PathIsRelativeW(self.wincode)
739
+ PathIsRelativeW(wincode)
737
740
  else
738
- root == "."
741
+ root == '.'
739
742
  end
740
743
  end
741
744
 
@@ -744,15 +747,15 @@ class Pathname < String
744
747
  #
745
748
  # Example:
746
749
  #
747
- # path = Pathname.new('/usr/./local/../bin')
750
+ # path = Pathname2.new('/usr/./local/../bin')
748
751
  # path.clean # => '/usr/bin'
749
752
  #
750
753
  def clean
751
- return self if self.empty?
754
+ return self if empty?
752
755
 
753
756
  if @win
754
757
  ptr = FFI::MemoryPointer.new(:char, MAXPATH)
755
- if PathCanonicalizeW(ptr, self.wincode)
758
+ if PathCanonicalizeW(ptr, wincode)
756
759
  return self.class.new(ptr.read_string(ptr.size).delete(0.chr))
757
760
  else
758
761
  return self
@@ -761,28 +764,28 @@ class Pathname < String
761
764
 
762
765
  final = []
763
766
 
764
- to_a.each{ |element|
765
- next if element == "."
767
+ to_a.each do |element|
768
+ next if element == '.'
766
769
  final.push(element)
767
- if element == ".." && self != ".."
770
+ if element == '..' && self != '..'
768
771
  2.times{ final.pop }
769
772
  end
770
- }
773
+ end
771
774
 
772
775
  final = final.join(@sep)
773
- final = root._plus_(final) if root != "."
774
- final = "." if final.empty?
776
+ final = root._plus_(final) if root != '.'
777
+ final = '.' if final.empty?
775
778
 
776
779
  self.class.new(final)
777
780
  end
778
781
 
779
- alias :cleanpath :clean
782
+ alias cleanpath clean
780
783
 
781
- # Identical to Pathname#clean, except that it modifies the receiver
784
+ # Identical to Pathname2#clean, except that it modifies the receiver
782
785
  # in place.
783
786
  #
784
787
  def clean!
785
- self.replace(clean)
788
+ replace(clean)
786
789
  end
787
790
 
788
791
  alias cleanpath! clean!
@@ -798,7 +801,7 @@ class Pathname < String
798
801
  #
799
802
  # Example:
800
803
  #
801
- # path = Pathname.new('/usr/local/bin/ruby')
804
+ # path = Pathname2.new('/usr/local/bin/ruby')
802
805
  #
803
806
  # puts path.dirname # => /usr/local/bin
804
807
  # puts path.dirname(2) # => /usr/local
@@ -807,15 +810,15 @@ class Pathname < String
807
810
  #
808
811
  def dirname(level = 1)
809
812
  raise ArgumentError if level < 0
810
- local_path = self.dup
813
+ local_path = dup
811
814
 
812
- level.times{ |n| local_path = File.dirname(local_path) }
815
+ level.times{ local_path = File.dirname(local_path) }
813
816
  self.class.new(local_path)
814
817
  end
815
818
 
816
- # Joins the given pathnames onto +self+ to create a new Pathname object.
819
+ # Joins the given pathnames onto +self+ to create a new Pathname2 object.
817
820
  #
818
- # path = Pathname.new("C:/Users")
821
+ # path = Pathname2.new("C:/Users")
819
822
  # path = path.join("foo", "Downloads") # => C:/Users/foo/Downloads
820
823
  #
821
824
  def join(*args)
@@ -824,11 +827,11 @@ class Pathname < String
824
827
  result = self.class.new(result) unless result === self.class
825
828
  return result if result.absolute?
826
829
 
827
- args.reverse_each{ |path|
830
+ args.reverse_each do |path|
828
831
  path = self.class.new(path) unless path === self.class
829
832
  result = path + result
830
833
  break if result.absolute?
831
- }
834
+ end
832
835
 
833
836
  result
834
837
  end
@@ -836,17 +839,17 @@ class Pathname < String
836
839
  # A custom pretty printer
837
840
  def pretty_print(q)
838
841
  if File::ALT_SEPARATOR
839
- q.text(self.to_s.tr(File::SEPARATOR, File::ALT_SEPARATOR))
842
+ q.text(to_s.tr(File::SEPARATOR, File::ALT_SEPARATOR))
840
843
  else
841
- q.text(self.to_s)
844
+ q.text(to_s)
842
845
  end
843
846
  end
844
847
 
845
848
  #-- Find facade
846
849
 
847
- # Pathname#find is an iterator to traverse a directory tree in a depth first
848
- # manner. It yields a Pathname for each file under the directory passed to
849
- # Pathname.new.
850
+ # Pathname2#find is an iterator to traverse a directory tree in a depth first
851
+ # manner. It yields a Pathname2 for each file under the directory passed to
852
+ # Pathname2.new.
850
853
  #
851
854
  # Since it is implemented by the Find module, Find.prune can be used to
852
855
  # control the traverse.
@@ -854,9 +857,9 @@ class Pathname < String
854
857
  # If +self+ is ".", yielded pathnames begin with a filename in the current
855
858
  # current directory, not ".".
856
859
  #
857
- def find(&block)
858
- require "find"
859
- if self == "."
860
+ def find
861
+ require 'find'
862
+ if self == '.'
860
863
  Find.find(self){ |f| yield self.class.new(f.sub(%r{\A\./}, '')) }
861
864
  else
862
865
  Find.find(self){ |f| yield self.class.new(f) }
@@ -867,17 +870,17 @@ class Pathname < String
867
870
 
868
871
  # IO.foreach
869
872
  def foreach(*args, &block)
870
- IO.foreach(self, *args, &block)
873
+ File.foreach(self, *args, &block)
871
874
  end
872
875
 
873
876
  # IO.read
874
877
  def read(*args)
875
- IO.read(self, *args)
878
+ File.read(self, *args)
876
879
  end
877
880
 
878
881
  # IO.readlines
879
882
  def readlines(*args)
880
- IO.readlines(self, *args)
883
+ File.readlines(self, *args)
881
884
  end
882
885
 
883
886
  # IO.sysopen
@@ -894,13 +897,13 @@ class Pathname < String
894
897
  # chdir to the path in question, then performs the glob.
895
898
  #
896
899
  def glob(*args)
897
- Dir.chdir(self){
900
+ Dir.chdir(self) do
898
901
  if block_given?
899
902
  Dir.glob(*args){ |file| yield self.class.new(file) }
900
903
  else
901
904
  Dir.glob(*args).map{ |file| self.class.new(file) }
902
905
  end
903
- }
906
+ end
904
907
  end
905
908
 
906
909
  # Dir.chdir
@@ -1042,7 +1045,7 @@ class Pathname < String
1042
1045
  FileUtils.mv(self, *args)
1043
1046
  end
1044
1047
 
1045
- # FileUtils.rm
1048
+ # FileUtils.rm
1046
1049
  def rm(*args)
1047
1050
  FileUtils.rm(self, *args)
1048
1051
  end
@@ -1110,31 +1113,26 @@ class Pathname < String
1110
1113
  end
1111
1114
  end
1112
1115
 
1116
+ # Re-open the Kernel module to add some global methods.
1113
1117
  module Kernel
1114
1118
  # Usage: pn{ path }
1115
1119
  #
1116
- # A shortcut for Pathname.new
1120
+ # A shortcut for Pathname2.new
1117
1121
  #
1118
1122
  def pn
1119
- instance_eval{ Pathname.new(yield) }
1120
- end
1121
-
1122
- begin
1123
- remove_method(:Pathname)
1124
- rescue NoMethodError, NameError
1125
- # Do nothing, not defined.
1123
+ instance_eval{ Pathname2.new(yield) }
1126
1124
  end
1127
1125
 
1128
- # Synonym for Pathname.new
1126
+ # Synonym for Pathname2.new
1129
1127
  #
1130
- def Pathname(path)
1131
- Pathname.new(path)
1128
+ def Pathname2(path)
1129
+ Pathname2.new(path)
1132
1130
  end
1133
1131
  end
1134
1132
 
1135
1133
  class String
1136
1134
  # Convert a string directly into a Pathname object.
1137
1135
  def to_path
1138
- Pathname.new(self)
1136
+ Pathname2.new(self)
1139
1137
  end
1140
1138
  end