pathname2 1.8.4 → 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 (45) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGES.md +7 -0
  4. data/Gemfile +2 -3
  5. data/MANIFEST.md +2 -2
  6. data/README.md +6 -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 +160 -169
  11. data/pathname2.gemspec +13 -9
  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 +61 -54
  44. metadata.gz.sig +0 -0
  45. 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,34 +37,31 @@ 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
- alias :_plus_ :+ # Used to prevent infinite loops in some cases
64
+ alias _plus_ + # Used to prevent infinite loops in some cases
68
65
 
69
66
  protected :_plus_
70
67
 
@@ -72,9 +69,9 @@ class Pathname < String
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,8 +83,8 @@ 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
91
88
 
92
89
  private_class_method :PathAppendW, :PathCanonicalizeW, :PathCreateFromUrlW
93
90
  private_class_method :PathGetDriveNumberW, :PathIsRelativeW, :PathIsRelativeW
@@ -98,14 +95,14 @@ class Pathname < String
98
95
  public
99
96
 
100
97
  # The version of the pathname2 library
101
- VERSION = '1.8.4'.freeze
98
+ VERSION = '2.0.0'.freeze
102
99
 
103
100
  # The maximum length of a path
104
101
  MAXPATH = 1024 unless defined? MAXPATH # Yes, I willfully violate POSIX
105
102
 
106
103
  # Returns the expanded path of the current working directory.
107
104
  #
108
- # Synonym for Pathname.new(Dir.pwd).
105
+ # Synonym for Pathname2.new(Dir.pwd).
109
106
  #
110
107
  def self.pwd
111
108
  new(Dir.pwd)
@@ -115,25 +112,25 @@ class Pathname < String
115
112
  alias getwd pwd
116
113
  end
117
114
 
118
- # Creates and returns a new Pathname object.
115
+ # Creates and returns a new Pathname2 object.
119
116
  #
120
117
  # On platforms that define File::ALT_SEPARATOR, all forward slashes are
121
118
  # replaced with the value of File::ALT_SEPARATOR. On MS Windows, for
122
119
  # example, all forward slashes are replaced with backslashes.
123
120
  #
124
- # 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
125
122
  # "file:///C:/Documents%20and%20Settings" will become 'C:\Documents and Settings'.
126
123
  #
127
124
  # Examples:
128
125
  #
129
- # Pathname.new("/foo/bar/baz")
130
- # Pathname.new("foo")
131
- # Pathname.new("file:///foo/bar/baz")
132
- # 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")
133
130
  #
134
131
  def initialize(path)
135
132
  if path.length > MAXPATH
136
- msg = "string too long. maximum string length is " + MAXPATH.to_s
133
+ msg = 'string too long. maximum string length is ' + MAXPATH.to_s
137
134
  raise ArgumentError, msg
138
135
  end
139
136
 
@@ -159,8 +156,8 @@ class Pathname < String
159
156
  end
160
157
  else
161
158
  if path.index('file:///', 0)
162
- require 'uri'
163
- path = URI::Parser.new.unescape(path)[7..-1]
159
+ require 'addressable'
160
+ path = Addressable::URI.unescape(path)[7..-1]
164
161
  end
165
162
  end
166
163
 
@@ -172,7 +169,7 @@ class Pathname < String
172
169
 
173
170
  # Returns a real (absolute) pathname of +self+ in the actual filesystem.
174
171
  #
175
- # Unlike most Pathname methods, this one assumes that the path actually
172
+ # Unlike most Pathname2 methods, this one assumes that the path actually
176
173
  # exists on your filesystem. If it doesn't, an error is raised. If a
177
174
  # circular symlink is encountered a system error will be raised.
178
175
  #
@@ -180,15 +177,15 @@ class Pathname < String
180
177
  #
181
178
  # Dir.pwd # => /usr/local
182
179
  # File.exists?('foo') # => true
183
- # Pathname.new('foo').realpath # => /usr/local/foo
180
+ # Pathname2.new('foo').realpath # => /usr/local/foo
184
181
  #
185
182
  def realpath
186
183
  File.stat(self) # Check to ensure that the path exists
187
184
 
188
185
  if File.symlink?(self)
189
- file = self.dup
186
+ file = dup
190
187
 
191
- while true
188
+ loop do
192
189
  file = File.join(File.dirname(file), File.readlink(file))
193
190
  break unless File.symlink?(file)
194
191
  end
@@ -200,7 +197,7 @@ class Pathname < String
200
197
  end
201
198
 
202
199
  # Returns the children of the directory, files and subdirectories, as an
203
- # 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
204
201
  # the returned pathnames will contain the filename only.
205
202
  #
206
203
  # Note that the result never contain the entries '.' and '..' in the
@@ -209,21 +206,21 @@ class Pathname < String
209
206
  #
210
207
  # Example:
211
208
  #
212
- # path = Pathname.new('/usr/bin')
209
+ # path = Pathname2.new('/usr/bin')
213
210
  # path.children # => ['/usr/bin/ruby', '/usr/bin/perl', ...]
214
211
  # path.children(false) # => ['ruby', 'perl', ...]
215
212
  #
216
213
  def children(with_directory = true)
217
214
  with_directory = false if self == '.'
218
215
  result = []
219
- Dir.foreach(self) { |file|
216
+ Dir.foreach(self) do |file|
220
217
  next if file == '.' || file == '..'
221
218
  if with_directory
222
219
  result << self.class.new(File.join(self, file))
223
220
  else
224
221
  result << self.class.new(file)
225
222
  end
226
- }
223
+ end
227
224
  result
228
225
  end
229
226
 
@@ -233,15 +230,15 @@ class Pathname < String
233
230
  #
234
231
  # Example:
235
232
  #
236
- # path = Pathname.new('C:\Path\File[5].txt')
233
+ # path = Pathname2.new('C:\Path\File[5].txt')
237
234
  # path.undecorate # => C:\Path\File.txt.
238
235
  #
239
236
  def undecorate
240
237
  unless @win
241
- raise NotImplementedError, "not supported on this platform"
238
+ raise NotImplementedError, 'not supported on this platform'
242
239
  end
243
240
 
244
- wpath = FFI::MemoryPointer.from_string(self.wincode)
241
+ wpath = FFI::MemoryPointer.from_string(wincode)
245
242
 
246
243
  PathUndecorateW(wpath)
247
244
 
@@ -250,10 +247,10 @@ class Pathname < String
250
247
 
251
248
  # Windows only
252
249
  #
253
- # Performs the substitution of Pathname#undecorate in place.
250
+ # Performs the substitution of Pathname2#undecorate in place.
254
251
  #
255
252
  def undecorate!
256
- self.replace(undecorate)
253
+ replace(undecorate)
257
254
  end
258
255
 
259
256
  # Windows only
@@ -262,14 +259,14 @@ class Pathname < String
262
259
  #
263
260
  # Example:
264
261
  #
265
- # path = Pathname.new('C:\Program Files\Java')
262
+ # path = Pathname2.new('C:\Program Files\Java')
266
263
  # path.short_path # => C:\Progra~1\Java.
267
264
  #
268
265
  def short_path
269
- raise NotImplementedError, "not supported on this platform" unless @win
266
+ raise NotImplementedError, 'not supported on this platform' unless @win
270
267
 
271
268
  buf = FFI::MemoryPointer.new(:char, MAXPATH)
272
- wpath = self.wincode
269
+ wpath = wincode
273
270
 
274
271
  size = GetShortPathNameW(wpath, buf, buf.size)
275
272
 
@@ -284,14 +281,14 @@ class Pathname < String
284
281
  #
285
282
  # Example:
286
283
  #
287
- # path = Pathname.new('C:\Progra~1\Java')
284
+ # path = Pathname2.new('C:\Progra~1\Java')
288
285
  # path.long_path # => C:\Program Files\Java.
289
286
  #
290
287
  def long_path
291
- raise NotImplementedError, "not supported on this platform" unless @win
288
+ raise NotImplementedError, 'not supported on this platform' unless @win
292
289
 
293
290
  buf = FFI::MemoryPointer.new(:char, MAXPATH)
294
- wpath = self.wincode
291
+ wpath = wincode
295
292
 
296
293
  size = GetLongPathNameW(wpath, buf, buf.size)
297
294
 
@@ -304,14 +301,14 @@ class Pathname < String
304
301
  #
305
302
  # Example:
306
303
  #
307
- # path = Pathname.new('/usr/local/')
304
+ # path = Pathname2.new('/usr/local/')
308
305
  # path.pstrip # => '/usr/local'
309
306
  #
310
307
  def pstrip
311
- str = self.dup
308
+ str = dup
312
309
  return str if str.empty?
313
310
 
314
- while ["/", "\\"].include?(str.to_s[-1].chr)
311
+ while [File::SEPARATOR, File::ALT_SEPARATOR].include?(str.to_s[-1].chr)
315
312
  str.strip!
316
313
  str.chop!
317
314
  end
@@ -319,18 +316,18 @@ class Pathname < String
319
316
  self.class.new(str)
320
317
  end
321
318
 
322
- # Performs the substitution of Pathname#pstrip in place.
319
+ # Performs the substitution of Pathname2#pstrip in place.
323
320
  #
324
321
  def pstrip!
325
- self.replace(pstrip)
322
+ replace(pstrip)
326
323
  end
327
324
 
328
325
  # Splits a pathname into strings based on the path separator.
329
326
  #
330
327
  # Examples:
331
328
  #
332
- # Pathname.new('/usr/local/bin').to_a # => ['usr', 'local', 'bin']
333
- # 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']
334
331
  #
335
332
  def to_a
336
333
  # Split string by path separator
@@ -339,7 +336,7 @@ class Pathname < String
339
336
  else
340
337
  array = split(@sep)
341
338
  end
342
- array.delete("") # Remove empty elements
339
+ array.delete('') # Remove empty elements
343
340
  array
344
341
  end
345
342
 
@@ -347,7 +344,7 @@ class Pathname < String
347
344
  #
348
345
  # Example:
349
346
  #
350
- # Pathname.new('/usr/local/bin').each{ |element|
347
+ # Pathname2.new('/usr/local/bin').each{ |element|
351
348
  # puts "Element: #{element}"
352
349
  # }
353
350
  #
@@ -365,13 +362,13 @@ class Pathname < String
365
362
  #
366
363
  # Examples:
367
364
  #
368
- # path = Pathname.new('/home/john/source/ruby')
365
+ # path = Pathname2.new('/home/john/source/ruby')
369
366
  # path[0] # => 'home'
370
367
  # path[1] # => 'john'
371
368
  # path[0, 3] # => '/home/john/source'
372
369
  # path[0..1] # => '/home/john'
373
370
  #
374
- # path = Pathname.new('C:/Documents and Settings/John/Source/Ruby')
371
+ # path = Pathname2.new('C:/Documents and Settings/John/Source/Ruby')
375
372
  # path[0] # => 'C:\'
376
373
  # path[1] # => 'Documents and Settings'
377
374
  # path[0, 3] # => 'C:\Documents and Settings\John'
@@ -390,22 +387,22 @@ class Pathname < String
390
387
  end
391
388
  path = File.join(to_a[index])
392
389
  else
393
- raise TypeError, "Only Numerics and Ranges allowed as first argument"
390
+ raise TypeError, 'Only Numerics and Ranges allowed as first argument'
394
391
  end
395
392
 
396
393
  if path && @win
397
- path = path.tr("/", "\\")
394
+ path = path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
398
395
  end
399
396
 
400
397
  path
401
398
  end
402
399
 
403
400
  # Yields each component of the path, concatenating the next component on
404
- # 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.
405
402
  #
406
403
  # Example:
407
404
  #
408
- # path = Pathname.new('/usr/local/bin')
405
+ # path = Pathname2.new('/usr/local/bin')
409
406
  #
410
407
  # path.descend{ |name|
411
408
  # puts name
@@ -423,9 +420,9 @@ class Pathname < String
423
420
  end
424
421
 
425
422
  if @win
426
- path = unc? ? "#{root}\\" : ""
423
+ path = unc? ? "#{root}\\" : ''
427
424
  else
428
- path = absolute? ? root : ""
425
+ path = absolute? ? root : ''
429
426
  end
430
427
 
431
428
  # Yield the root directory if an absolute path (and not Windows)
@@ -433,21 +430,21 @@ class Pathname < String
433
430
  yield root if absolute?
434
431
  end
435
432
 
436
- each{ |element|
433
+ each do |element|
437
434
  if @win && unc?
438
435
  next if root.to_a.include?(element)
439
436
  end
440
437
  path << element << @sep
441
438
  yield self.class.new(path.chop)
442
- }
439
+ end
443
440
  end
444
441
 
445
442
  # Yields the path, minus one component on each iteration, as a new
446
- # Pathname object, ending with the root path.
443
+ # Pathname2 object, ending with the root path.
447
444
  #
448
445
  # Example:
449
446
  #
450
- # path = Pathname.new('/usr/local/bin')
447
+ # path = Pathname2.new('/usr/local/bin')
451
448
  #
452
449
  # path.ascend{ |name|
453
450
  # puts name
@@ -502,24 +499,24 @@ class Pathname < String
502
499
  #
503
500
  # Examples:
504
501
  #
505
- # Pathname.new('/usr/local').root # => '/'
506
- # Pathname.new('lib').root # => '.'
502
+ # Pathname2.new('/usr/local').root # => '/'
503
+ # Pathname2.new('lib').root # => '.'
507
504
  #
508
505
  # On MS Windows:
509
506
  #
510
- # Pathname.new('C:\WINNT').root # => 'C:'
511
- # Pathname.new('\\some\share\foo').root # => '\\some\share'
507
+ # Pathname2.new('C:\WINNT').root # => 'C:'
508
+ # Pathname2.new('\\some\share\foo').root # => '\\some\share'
512
509
  #
513
510
  def root
514
- dir = "."
511
+ dir = '.'
515
512
 
516
513
  if @win
517
- wpath = FFI::MemoryPointer.from_string(self.wincode)
514
+ wpath = FFI::MemoryPointer.from_string(wincode)
518
515
  if PathStripToRootW(wpath)
519
516
  dir = wpath.read_string(wpath.size).split("\000\000").first.tr(0.chr, '')
520
517
  end
521
518
  else
522
- dir = "/" if self =~ /^\//
519
+ dir = '/' if self =~ /^\//
523
520
  end
524
521
 
525
522
  self.class.new(dir)
@@ -529,12 +526,12 @@ class Pathname < String
529
526
  #
530
527
  # Examples:
531
528
  #
532
- # Pathname.new('/').root? # => true
533
- # Pathname.new('/foo').root? # => false
529
+ # Pathname2.new('/').root? # => true
530
+ # Pathname2.new('/foo').root? # => false
534
531
  #
535
532
  def root?
536
533
  if @win
537
- PathIsRootW(self.wincode)
534
+ PathIsRootW(wincode)
538
535
  else
539
536
  self == root
540
537
  end
@@ -547,12 +544,12 @@ class Pathname < String
547
544
  #
548
545
  # Examples:
549
546
  #
550
- # Pathname.new("\\\\foo\\bar").unc? # => true
551
- # Pathname.new('C:\Program Files').unc? # => false
547
+ # Pathname2.new("\\\\foo\\bar").unc? # => true
548
+ # Pathname2.new('C:\Program Files').unc? # => false
552
549
  #
553
550
  def unc?
554
- raise NotImplementedError, "not supported on this platform" unless @win
555
- PathIsUNCW(self.wincode)
551
+ raise NotImplementedError, 'not supported on this platform' unless @win
552
+ PathIsUNCW(wincode)
556
553
  end
557
554
 
558
555
  # MS Windows only
@@ -562,31 +559,32 @@ class Pathname < String
562
559
  #
563
560
  # Example:
564
561
  #
565
- # Pathname.new("C:\\foo").drive_number # => 2
562
+ # Pathname2.new("C:\\foo").drive_number # => 2
566
563
  #
567
564
  def drive_number
568
565
  unless @win
569
- raise NotImplementedError, "not supported on this platform"
566
+ raise NotImplementedError, 'not supported on this platform'
570
567
  end
571
568
 
572
- num = PathGetDriveNumberW(self.wincode)
569
+ num = PathGetDriveNumberW(wincode)
573
570
  num >= 0 ? num : nil
574
571
  end
575
572
 
576
- # Compares two Pathname objects. Note that Pathnames may only be compared
577
- # 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.
578
576
  #
579
577
  # Example:
580
578
  #
581
- # path1 = Pathname.new('/usr/local')
582
- # path2 = Pathname.new('/usr/local')
583
- # 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')
584
582
  #
585
583
  # path1 <=> path2 # => 0
586
584
  # path1 <=> path3 # => -1
587
585
  #
588
586
  def <=>(string)
589
- return nil unless string.kind_of?(Pathname)
587
+ return nil unless string.is_a?(Pathname2)
590
588
  super
591
589
  end
592
590
 
@@ -594,11 +592,11 @@ class Pathname < String
594
592
  #
595
593
  # Example:
596
594
  #
597
- # Pathname.new('/usr/local/bin').parent # => '/usr/local'
595
+ # Pathname2.new('/usr/local/bin').parent # => '/usr/local'
598
596
  #
599
597
  def parent
600
598
  return self if root?
601
- self + ".." # Use our custom '+' method
599
+ self + '..' # Use our custom '+' method
602
600
  end
603
601
 
604
602
  # Returns a relative path from the argument to the receiver. If +self+
@@ -614,23 +612,23 @@ class Pathname < String
614
612
  #
615
613
  # Examples:
616
614
  #
617
- # path = Pathname.new('/usr/local/bin')
615
+ # path = Pathname2.new('/usr/local/bin')
618
616
  # path.relative_path_from('/usr/bin') # => "../local/bin"
619
617
  #
620
- # path = Pathname.new("C:\\WINNT\\Fonts")
618
+ # path = Pathname2.new("C:\\WINNT\\Fonts")
621
619
  # path.relative_path_from("C:\\Program Files") # => "..\\WINNT\\Fonts"
622
620
  #
623
621
  def relative_path_from(base)
624
- base = self.class.new(base) unless base.kind_of?(Pathname)
622
+ base = self.class.new(base) unless base.is_a?(Pathname2)
625
623
 
626
- if self.absolute? != base.absolute?
627
- raise ArgumentError, "relative path between absolute and relative path"
624
+ if absolute? != base.absolute?
625
+ raise ArgumentError, 'relative path between absolute and relative path'
628
626
  end
629
627
 
630
- return self.class.new(".") if self == base
631
- return self if base == "."
628
+ return self.class.new('.') if self == base
629
+ return self if base == '.'
632
630
 
633
- # 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
634
632
  # a little extra help here.
635
633
  if @win
636
634
  if root != base.root
@@ -642,7 +640,7 @@ class Pathname < String
642
640
  end
643
641
  end
644
642
 
645
- dest_arr = self.clean.to_a
643
+ dest_arr = clean.to_a
646
644
  base_arr = base.clean.to_a
647
645
  dest_arr.delete('.')
648
646
  base_arr.delete('.')
@@ -654,22 +652,22 @@ class Pathname < String
654
652
  dest_arr.shift
655
653
  end
656
654
 
657
- if base_arr.include?("..")
655
+ if base_arr.include?('..')
658
656
  raise ArgumentError, "base directory may not contain '..'"
659
657
  end
660
658
 
661
- base_arr.fill("..")
659
+ base_arr.fill('..')
662
660
  rel_path = base_arr + dest_arr
663
661
 
664
662
  if rel_path.empty?
665
- self.class.new(".")
663
+ self.class.new('.')
666
664
  else
667
665
  self.class.new(rel_path.join(@sep))
668
666
  end
669
667
  end
670
668
 
671
- # Adds two Pathname objects together, or a Pathname and a String. It
672
- # also automatically cleans the Pathname.
669
+ # Adds two Pathname2 objects together, or a Pathname2 and a String. It
670
+ # also automatically cleans the Pathname2.
673
671
  #
674
672
  # Adding a root path to an existing path merely replaces the current
675
673
  # path. Adding '.' to an existing path does nothing.
@@ -681,18 +679,18 @@ class Pathname < String
681
679
  # path1 + path2 # '/foo/baz'
682
680
  #
683
681
  def +(string)
684
- unless string.kind_of?(Pathname)
682
+ unless string.is_a?(Pathname2)
685
683
  string = self.class.new(string)
686
684
  end
687
685
 
688
686
  # Any path plus "." is the same directory
689
- return self if string == "."
690
- return string if self == "."
687
+ return self if string == '.'
688
+ return string if self == '.'
691
689
 
692
690
  # Use the builtin PathAppend() function if on Windows - much easier
693
691
  if @win
694
692
  path = FFI::MemoryPointer.new(:char, MAXPATH)
695
- path.write_string(self.dup.wincode)
693
+ path.write_string(dup.wincode)
696
694
  more = FFI::MemoryPointer.from_string(string.wincode)
697
695
 
698
696
  PathAppendW(path, more)
@@ -716,14 +714,14 @@ class Pathname < String
716
714
  self.class.new(new_string).clean
717
715
  end
718
716
 
719
- alias :/ :+
717
+ alias / +
720
718
 
721
719
  # Returns whether or not the path is an absolute path.
722
720
  #
723
721
  # Example:
724
722
  #
725
- # Pathname.new('/usr/bin').absolute? # => true
726
- # Pathname.new('usr').absolute? # => false
723
+ # Pathname2.new('/usr/bin').absolute? # => true
724
+ # Pathname2.new('usr').absolute? # => false
727
725
  #
728
726
  def absolute?
729
727
  !relative?
@@ -733,14 +731,14 @@ class Pathname < String
733
731
  #
734
732
  # Example:
735
733
  #
736
- # Pathname.new('/usr/bin').relative? # => true
737
- # Pathname.new('usr').relative? # => false
734
+ # Pathname2.new('/usr/bin').relative? # => true
735
+ # Pathname2.new('usr').relative? # => false
738
736
  #
739
737
  def relative?
740
738
  if @win
741
- PathIsRelativeW(self.wincode)
739
+ PathIsRelativeW(wincode)
742
740
  else
743
- root == "."
741
+ root == '.'
744
742
  end
745
743
  end
746
744
 
@@ -749,15 +747,15 @@ class Pathname < String
749
747
  #
750
748
  # Example:
751
749
  #
752
- # path = Pathname.new('/usr/./local/../bin')
750
+ # path = Pathname2.new('/usr/./local/../bin')
753
751
  # path.clean # => '/usr/bin'
754
752
  #
755
753
  def clean
756
- return self if self.empty?
754
+ return self if empty?
757
755
 
758
756
  if @win
759
757
  ptr = FFI::MemoryPointer.new(:char, MAXPATH)
760
- if PathCanonicalizeW(ptr, self.wincode)
758
+ if PathCanonicalizeW(ptr, wincode)
761
759
  return self.class.new(ptr.read_string(ptr.size).delete(0.chr))
762
760
  else
763
761
  return self
@@ -766,28 +764,28 @@ class Pathname < String
766
764
 
767
765
  final = []
768
766
 
769
- to_a.each{ |element|
770
- next if element == "."
767
+ to_a.each do |element|
768
+ next if element == '.'
771
769
  final.push(element)
772
- if element == ".." && self != ".."
770
+ if element == '..' && self != '..'
773
771
  2.times{ final.pop }
774
772
  end
775
- }
773
+ end
776
774
 
777
775
  final = final.join(@sep)
778
- final = root._plus_(final) if root != "."
779
- final = "." if final.empty?
776
+ final = root._plus_(final) if root != '.'
777
+ final = '.' if final.empty?
780
778
 
781
779
  self.class.new(final)
782
780
  end
783
781
 
784
- alias :cleanpath :clean
782
+ alias cleanpath clean
785
783
 
786
- # Identical to Pathname#clean, except that it modifies the receiver
784
+ # Identical to Pathname2#clean, except that it modifies the receiver
787
785
  # in place.
788
786
  #
789
787
  def clean!
790
- self.replace(clean)
788
+ replace(clean)
791
789
  end
792
790
 
793
791
  alias cleanpath! clean!
@@ -803,7 +801,7 @@ class Pathname < String
803
801
  #
804
802
  # Example:
805
803
  #
806
- # path = Pathname.new('/usr/local/bin/ruby')
804
+ # path = Pathname2.new('/usr/local/bin/ruby')
807
805
  #
808
806
  # puts path.dirname # => /usr/local/bin
809
807
  # puts path.dirname(2) # => /usr/local
@@ -812,15 +810,15 @@ class Pathname < String
812
810
  #
813
811
  def dirname(level = 1)
814
812
  raise ArgumentError if level < 0
815
- local_path = self.dup
813
+ local_path = dup
816
814
 
817
815
  level.times{ local_path = File.dirname(local_path) }
818
816
  self.class.new(local_path)
819
817
  end
820
818
 
821
- # 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.
822
820
  #
823
- # path = Pathname.new("C:/Users")
821
+ # path = Pathname2.new("C:/Users")
824
822
  # path = path.join("foo", "Downloads") # => C:/Users/foo/Downloads
825
823
  #
826
824
  def join(*args)
@@ -829,11 +827,11 @@ class Pathname < String
829
827
  result = self.class.new(result) unless result === self.class
830
828
  return result if result.absolute?
831
829
 
832
- args.reverse_each{ |path|
830
+ args.reverse_each do |path|
833
831
  path = self.class.new(path) unless path === self.class
834
832
  result = path + result
835
833
  break if result.absolute?
836
- }
834
+ end
837
835
 
838
836
  result
839
837
  end
@@ -841,17 +839,17 @@ class Pathname < String
841
839
  # A custom pretty printer
842
840
  def pretty_print(q)
843
841
  if File::ALT_SEPARATOR
844
- q.text(self.to_s.tr(File::SEPARATOR, File::ALT_SEPARATOR))
842
+ q.text(to_s.tr(File::SEPARATOR, File::ALT_SEPARATOR))
845
843
  else
846
- q.text(self.to_s)
844
+ q.text(to_s)
847
845
  end
848
846
  end
849
847
 
850
848
  #-- Find facade
851
849
 
852
- # Pathname#find is an iterator to traverse a directory tree in a depth first
853
- # manner. It yields a Pathname for each file under the directory passed to
854
- # 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.
855
853
  #
856
854
  # Since it is implemented by the Find module, Find.prune can be used to
857
855
  # control the traverse.
@@ -861,7 +859,7 @@ class Pathname < String
861
859
  #
862
860
  def find
863
861
  require 'find'
864
- if self == "."
862
+ if self == '.'
865
863
  Find.find(self){ |f| yield self.class.new(f.sub(%r{\A\./}, '')) }
866
864
  else
867
865
  Find.find(self){ |f| yield self.class.new(f) }
@@ -872,17 +870,17 @@ class Pathname < String
872
870
 
873
871
  # IO.foreach
874
872
  def foreach(*args, &block)
875
- IO.foreach(self, *args, &block)
873
+ File.foreach(self, *args, &block)
876
874
  end
877
875
 
878
876
  # IO.read
879
877
  def read(*args)
880
- IO.read(self, *args)
878
+ File.read(self, *args)
881
879
  end
882
880
 
883
881
  # IO.readlines
884
882
  def readlines(*args)
885
- IO.readlines(self, *args)
883
+ File.readlines(self, *args)
886
884
  end
887
885
 
888
886
  # IO.sysopen
@@ -899,13 +897,13 @@ class Pathname < String
899
897
  # chdir to the path in question, then performs the glob.
900
898
  #
901
899
  def glob(*args)
902
- Dir.chdir(self){
900
+ Dir.chdir(self) do
903
901
  if block_given?
904
902
  Dir.glob(*args){ |file| yield self.class.new(file) }
905
903
  else
906
904
  Dir.glob(*args).map{ |file| self.class.new(file) }
907
905
  end
908
- }
906
+ end
909
907
  end
910
908
 
911
909
  # Dir.chdir
@@ -1047,7 +1045,7 @@ class Pathname < String
1047
1045
  FileUtils.mv(self, *args)
1048
1046
  end
1049
1047
 
1050
- # FileUtils.rm
1048
+ # FileUtils.rm
1051
1049
  def rm(*args)
1052
1050
  FileUtils.rm(self, *args)
1053
1051
  end
@@ -1115,33 +1113,26 @@ class Pathname < String
1115
1113
  end
1116
1114
  end
1117
1115
 
1116
+ # Re-open the Kernel module to add some global methods.
1118
1117
  module Kernel
1119
1118
  # Usage: pn{ path }
1120
1119
  #
1121
- # A shortcut for Pathname.new
1120
+ # A shortcut for Pathname2.new
1122
1121
  #
1123
1122
  def pn
1124
- instance_eval{ Pathname.new(yield) }
1125
- end
1126
-
1127
- # rubocop:disable Lint/ShadowedException
1128
- begin
1129
- remove_method(:Pathname)
1130
- rescue NoMethodError, NameError
1131
- # Do nothing, not defined.
1123
+ instance_eval{ Pathname2.new(yield) }
1132
1124
  end
1133
- # rubocop:enable Lint/ShadowedException
1134
1125
 
1135
- # Synonym for Pathname.new
1126
+ # Synonym for Pathname2.new
1136
1127
  #
1137
- def Pathname(path)
1138
- Pathname.new(path)
1128
+ def Pathname2(path)
1129
+ Pathname2.new(path)
1139
1130
  end
1140
1131
  end
1141
1132
 
1142
1133
  class String
1143
1134
  # Convert a string directly into a Pathname object.
1144
1135
  def to_path
1145
- Pathname.new(self)
1136
+ Pathname2.new(self)
1146
1137
  end
1147
1138
  end