Class: Pathname

Inherits:
Object
  • Object
show all
Defined in:
lib/pathname.rb,
pathname.c,
lib/pathname.rb,
lib/pathname.rb

Overview

  • FileUtils *

Constant Summary collapse

TO_PATH =

to_path is implemented so Pathname objects are usable with File.open, etc.

:to_path
SAME_PATHS =
if File::FNM_SYSCASE.nonzero?
  proc {|a, b| a.casecmp(b).zero?}
else
  proc {|a, b| a == b}
end
SEPARATOR_LIST =
"#{Regexp.quote File::SEPARATOR}"
SEPARATOR_PAT =
/#{Regexp.quote File::SEPARATOR}/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeObject

Create a Pathname object from the given String (or String-like object). If path contains a NUL character (\0), an ArgumentError is raised.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'pathname.c', line 26

static VALUE
path_initialize(VALUE self, VALUE arg)
{
    VALUE str;
    if (TYPE(arg) == T_STRING) {
        str = arg;
    }
    else {
        str = rb_check_funcall(arg, id_to_path, 0, NULL);
        if (str == Qundef)
            str = arg;
        StringValue(str);
    }
    if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str)))
        rb_raise(rb_eArgError, "pathname contains null byte");
    str = rb_obj_dup(str);

    set_strpath(self, str);
    OBJ_INFECT(self, str);
    return self;
}

Class Method Details

.getwdObject

See Dir.getwd. Returns the current working directory as a Pathname.



852
853
854
855
856
857
858
# File 'pathname.c', line 852

static VALUE
path_s_getwd(VALUE klass)
{
    VALUE str;
    str = rb_funcall(rb_cDir, rb_intern("getwd"), 0);
    return rb_class_new_instance(1, &str, klass);
}

.globObject

See Dir.glob. Returns or yields Pathname objects.



825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
# File 'pathname.c', line 825

static VALUE
path_s_glob(int argc, VALUE *argv, VALUE klass)
{
    VALUE args[2];
    int n;

    n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cDir, rb_intern("glob"), n, args, glob_i, klass);
    }
    else {
        VALUE ary;
        long i;
        ary = rb_funcall2(rb_cDir, rb_intern("glob"), n, args);
        ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            VALUE elt = RARRAY_PTR(ary)[i];
            elt = rb_class_new_instance(1, &elt, klass);
            rb_ary_store(ary, i, elt);
        }
        return ary;
    }
}

.pwdObject

See Dir.getwd. Returns the current working directory as a Pathname.



852
853
854
855
856
857
858
# File 'pathname.c', line 852

static VALUE
path_s_getwd(VALUE klass)
{
    VALUE str;
    str = rb_funcall(rb_cDir, rb_intern("getwd"), 0);
    return rb_class_new_instance(1, &str, klass);
}

Instance Method Details

#+(other) ⇒ Object

Pathname#+ appends a pathname fragment to this one to produce a new Pathname object.

p1 = Pathname.new("/usr")      # Pathname:/usr
p2 = p1 + "bin/ruby"           # Pathname:/usr/bin/ruby
p3 = p1 + "/etc/passwd"        # Pathname:/etc/passwd

This method doesn't access the file system; it is pure string manipulation.



307
308
309
310
# File 'lib/pathname.rb', line 307

def +(other)
  other = Pathname.new(other) unless Pathname === other
  Pathname.new(plus(@path, other.to_s))
end

#<=>Object

Provides for comparing pathnames, case-sensitively.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'pathname.c', line 88

static VALUE
path_cmp(VALUE self, VALUE other)
{
    VALUE s1, s2;
    char *p1, *p2;
    char *e1, *e2;
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qnil;
    s1 = get_strpath(self);
    s2 = get_strpath(other);
    p1 = RSTRING_PTR(s1);
    p2 = RSTRING_PTR(s2);
    e1 = p1 + RSTRING_LEN(s1);
    e2 = p2 + RSTRING_LEN(s2);
    while (p1 < e1 && p2 < e2) {
        int c1, c2;
        c1 = (unsigned char)*p1++;
        c2 = (unsigned char)*p2++;
        if (c1 == '/') c1 = '\0';
        if (c2 == '/') c2 = '\0';
        if (c1 != c2) {
            if (c1 < c2)
                return INT2FIX(-1);
            else
                return INT2FIX(1);
        }
    }
    if (p1 < e1)
        return INT2FIX(1);
    if (p2 < e2)
        return INT2FIX(-1);
    return INT2FIX(0);
}

#==Object

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.



77
78
79
80
81
82
83
# File 'pathname.c', line 77

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}

#===Object

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.



77
78
79
80
81
82
83
# File 'pathname.c', line 77

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}

#absolute?Boolean

Predicate method for testing whether a path is absolute. It returns true if the pathname begins with a slash.

Returns:

  • (Boolean)


214
215
216
# File 'lib/pathname.rb', line 214

def absolute?
  !relative?
end

#ascend {|_self| ... } ⇒ Object

Iterates over and yields a new Pathname object for each element in the given path in ascending order.

Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
   #<Pathname:/path/to/some/file.rb>
   #<Pathname:/path/to/some>
   #<Pathname:/path/to>
   #<Pathname:/path>
   #<Pathname:/>

Pathname.new('path/to/some/file.rb').ascend {|v| p v}
   #<Pathname:path/to/some/file.rb>
   #<Pathname:path/to/some>
   #<Pathname:path/to>
   #<Pathname:path>

It doesn't access actual filesystem.

This method is available since 1.8.5.

Yields:

  • (_self)

Yield Parameters:

  • _self (Pathname)

    the object that the method was called on



287
288
289
290
291
292
293
294
295
# File 'lib/pathname.rb', line 287

def ascend
  path = @path
  yield self
  while r = chop_basename(path)
    path, = r
    break if path.empty?
    yield self.class.new(del_trailing_separator(path))
  end
end

#atimeObject

See File.atime. Returns last access time.



344
345
346
347
348
# File 'pathname.c', line 344

static VALUE
path_atime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("atime"), 1, get_strpath(self));
}

#basenameObject

See File.basename. Returns the last component of the path.



535
536
537
538
539
540
541
542
543
544
545
# File 'pathname.c', line 535

static VALUE
path_basename(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE fext;
    if (rb_scan_args(argc, argv, "01", &fext) == 0)
        str = rb_funcall(rb_cFile, rb_intern("basename"), 1, str);
    else
        str = rb_funcall(rb_cFile, rb_intern("basename"), 2, str, fext);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#binread([length [, offset]]) ⇒ String

See IO.binread. Returns all the bytes from the file, or the first N if specified.

Returns:

  • (String)


292
293
294
295
296
297
298
299
300
301
# File 'pathname.c', line 292

static VALUE
path_binread(int argc, VALUE *argv, VALUE self)
{
    VALUE args[3];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
    return rb_funcall2(rb_cIO, rb_intern("binread"), 1+n, args);
}

#blockdev?Boolean

See FileTest.blockdev?.

Returns:

  • (Boolean)


603
604
605
606
607
# File 'pathname.c', line 603

static VALUE
path_blockdev_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("blockdev?"), 1, get_strpath(self));
}

#chardev?Boolean

See FileTest.chardev?.

Returns:

  • (Boolean)


612
613
614
615
616
# File 'pathname.c', line 612

static VALUE
path_chardev_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("chardev?"), 1, get_strpath(self));
}

#children(with_directory = true) ⇒ Object

Returns the children of the directory (files and subdirectories, not recursive) as an array of Pathname objects. By default, the returned pathnames will have enough information to access the files. If you set with_directory to false, then the returned pathnames will contain the filename only.

For example:

pn = Pathname("/usr/lib/ruby/1.8")
pn.children
    # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
           Pathname:/usr/lib/ruby/1.8/Env.rb,
           Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
pn.children(false)
    # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]

Note that the results never contain the entries . and .. in the directory because they are not children.

This method has existed since 1.8.1.



394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/pathname.rb', line 394

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

#chmodObject

See File.chmod. Changes permissions.



371
372
373
374
375
# File 'pathname.c', line 371

static VALUE
path_chmod(VALUE self, VALUE mode)
{
    return rb_funcall(rb_cFile, rb_intern("chmod"), 2, mode, get_strpath(self));
}

#chownObject

See File.chown. Change owner and group of file.



389
390
391
392
393
# File 'pathname.c', line 389

static VALUE
path_chown(VALUE self, VALUE owner, VALUE group)
{
    return rb_funcall(rb_cFile, rb_intern("chown"), 3, owner, group, get_strpath(self));
}

#cleanpath(consider_symlink = false) ⇒ Object

Returns clean pathname of self with consecutive slashes and useless dots removed. The filesystem is not accessed.

If consider_symlink is true, then a more conservative algorithm is used to avoid breaking symbolic linkages. This may retain more .. entries than absolutely necessary, but without accessing the filesystem, this can't be avoided. See #realpath.



85
86
87
88
89
90
91
# File 'lib/pathname.rb', line 85

def cleanpath(consider_symlink=false)
  if consider_symlink
    cleanpath_conservative
  else
    cleanpath_aggressive
  end
end

#ctimeObject

See File.ctime. Returns last (directory entry, not file) change time.



353
354
355
356
357
# File 'pathname.c', line 353

static VALUE
path_ctime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("ctime"), 1, get_strpath(self));
}

#deleteObject

Removes a file or directory, using File.unlink or Dir.unlink as necessary.



956
957
958
959
960
961
962
# File 'pathname.c', line 956

static VALUE
path_unlink(VALUE self)
{
    VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR"));
    VALUE str = get_strpath(self);
    return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
}

#descendObject

Iterates over and yields a new Pathname object for each element in the given path in descending order.

Pathname.new('/path/to/some/file.rb').descend {|v| p v}
   #<Pathname:/>
   #<Pathname:/path>
   #<Pathname:/path/to>
   #<Pathname:/path/to/some>
   #<Pathname:/path/to/some/file.rb>

Pathname.new('path/to/some/file.rb').descend {|v| p v}
   #<Pathname:path>
   #<Pathname:path/to>
   #<Pathname:path/to/some>
   #<Pathname:path/to/some/file.rb>

It doesn't access actual filesystem.

This method is available since 1.8.5.



260
261
262
263
264
265
# File 'lib/pathname.rb', line 260

def descend
  vs = []
  ascend {|v| vs << v }
  vs.reverse_each {|v| yield v }
  nil
end

#directory?Boolean

See FileTest.directory?.

Returns:

  • (Boolean)


657
658
659
660
661
# File 'pathname.c', line 657

static VALUE
path_directory_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("directory?"), 1, get_strpath(self));
}

#dirnameObject

See File.dirname. Returns all but the last component of the path.



550
551
552
553
554
555
556
# File 'pathname.c', line 550

static VALUE
path_dirname(VALUE self)
{
    VALUE str = get_strpath(self);
    str = rb_funcall(rb_cFile, rb_intern("dirname"), 1, str);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#each_child(with_directory = true, &b) ⇒ Object

Iterates over the children of the directory (files and subdirectories, not recursive). It yields Pathname object for each child. By default, the yielded pathnames will have enough information to access the files. If you set with_directory to false, then the returned pathnames will contain the filename only.

Pathname("/usr/local").each_child {|f| p f }
#=> #<Pathname:/usr/local/share>
#   #<Pathname:/usr/local/bin>
#   #<Pathname:/usr/local/games>
#   #<Pathname:/usr/local/lib>
#   #<Pathname:/usr/local/include>
#   #<Pathname:/usr/local/sbin>
#   #<Pathname:/usr/local/src>
#   #<Pathname:/usr/local/man>

Pathname("/usr/local").each_child(false) {|f| p f }
#=> #<Pathname:share>
#   #<Pathname:bin>
#   #<Pathname:games>
#   #<Pathname:lib>
#   #<Pathname:include>
#   #<Pathname:sbin>
#   #<Pathname:src>
#   #<Pathname:man>


434
435
436
# File 'lib/pathname.rb', line 434

def each_child(with_directory=true, &b)
  children(with_directory).each(&b)
end

#each_entryObject

Iterates over the entries (files and subdirectories) in the directory. It yields a Pathname object for each entry.

This method has available since 1.8.1.



931
932
933
934
935
936
937
938
# File 'pathname.c', line 931

static VALUE
path_each_entry(VALUE self)
{
    VALUE args[1];

    args[0] = get_strpath(self);
    return rb_block_call(rb_cDir, rb_intern("foreach"), 1, args, each_entry_i, rb_obj_class(self));
}

#each_filenameObject

Iterates over each component of the path.

Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
  # yields "usr", "bin", and "ruby".


233
234
235
236
237
238
# File 'lib/pathname.rb', line 233

def each_filename # :yield: filename
  return to_enum(__method__) unless block_given?
  _, names = split_names(@path)
  names.each {|filename| yield filename }
  nil
end

#each_line {|line| ... } ⇒ Object #each_line(sep = $/[, open_args]) {|line| ... } ⇒ nil #each_line(limit[, open_args]) {|line| ... } ⇒ nil #each_line(sep, limit[, open_args]) {|line| ... } ⇒ nil #each_line(...) ⇒ Object

#each_line iterates over the line in the file. It yields a String object for each line.

This method is availabel since 1.8.1.

Overloads:

  • #each_line {|line| ... } ⇒ Object

    Yields:

    • (line)
  • #each_line(sep = $/[, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)
  • #each_line(limit[, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)
  • #each_line(sep, limit[, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)


248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'pathname.c', line 248

static VALUE
path_each_line(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cIO, rb_intern("foreach"), 1+n, args, 0, 0);
    }
    else {
        return rb_funcall2(rb_cIO, rb_intern("foreach"), 1+n, args);
    }
}

#entriesObject

Return the entries (files and subdirectories) in the directory, each as a Pathname object.

The result may contain the current directory #<Pathname:.> and the parent directory #<Pathname:..>.



867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
# File 'pathname.c', line 867

static VALUE
path_entries(VALUE self)
{
    VALUE klass, str, ary;
    long i;
    klass = rb_obj_class(self);
    str = get_strpath(self);
    ary = rb_funcall(rb_cDir, rb_intern("entries"), 1, str);
    ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        VALUE elt = RARRAY_PTR(ary)[i];
        elt = rb_class_new_instance(1, &elt, klass);
        rb_ary_store(ary, i, elt);
    }
    return ary;
}

#eql?Boolean

Compare this pathname with other. The comparison is string-based. Be aware that two different paths (foo.txt and ./foo.txt) can refer to the same file.

Returns:

  • (Boolean)


77
78
79
80
81
82
83
# File 'pathname.c', line 77

static VALUE
path_eq(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cPathname))
        return Qfalse;
    return rb_str_equal(get_strpath(self), get_strpath(other));
}

#executable?Boolean

See FileTest.executable?.

Returns:

  • (Boolean)


621
622
623
624
625
# File 'pathname.c', line 621

static VALUE
path_executable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("executable?"), 1, get_strpath(self));
}

#executable_real?Boolean

See FileTest.executable_real?.

Returns:

  • (Boolean)


630
631
632
633
634
# File 'pathname.c', line 630

static VALUE
path_executable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("executable_real?"), 1, get_strpath(self));
}

#exist?Boolean

See FileTest.exist?.

Returns:

  • (Boolean)


639
640
641
642
643
# File 'pathname.c', line 639

static VALUE
path_exist_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("exist?"), 1, get_strpath(self));
}

#expand_pathObject

See File.expand_path.



571
572
573
574
575
576
577
578
579
580
581
# File 'pathname.c', line 571

static VALUE
path_expand_path(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE dname;
    if (rb_scan_args(argc, argv, "01", &dname) == 0)
        str = rb_funcall(rb_cFile, rb_intern("expand_path"), 1, str);
    else
        str = rb_funcall(rb_cFile, rb_intern("expand_path"), 2, str, dname);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#extnameObject

See File.extname. Returns the file's extension.



561
562
563
564
565
566
# File 'pathname.c', line 561

static VALUE
path_extname(VALUE self)
{
    VALUE str = get_strpath(self);
    return rb_funcall(rb_cFile, rb_intern("extname"), 1, str);
}

#file?Boolean

See FileTest.file?.

Returns:

  • (Boolean)


666
667
668
669
670
# File 'pathname.c', line 666

static VALUE
path_file_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("file?"), 1, get_strpath(self));
}

#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 "this" directory.

Since it is implemented by find.rb, Find.prune can be used to control the traversal.

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



498
499
500
501
502
503
504
505
# File 'lib/pathname.rb', line 498

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

#fnmatch(pattern, [flags]) ⇒ String #fnmatch?(pattern, [flags]) ⇒ String

See File.fnmatch. Return true if the receiver matches the given pattern.

Overloads:

  • #fnmatch(pattern, [flags]) ⇒ String

    Returns:

    • (String)
  • #fnmatch?(pattern, [flags]) ⇒ String

    Returns:

    • (String)


412
413
414
415
416
417
418
419
420
421
# File 'pathname.c', line 412

static VALUE
path_fnmatch(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE pattern, flags;
    if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1)
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 2, pattern, str);
    else
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 3, pattern, str, flags);
}

#fnmatch(pattern, [flags]) ⇒ String #fnmatch?(pattern, [flags]) ⇒ String

See File.fnmatch. Return true if the receiver matches the given pattern.

Overloads:

  • #fnmatch(pattern, [flags]) ⇒ String

    Returns:

    • (String)
  • #fnmatch?(pattern, [flags]) ⇒ String

    Returns:

    • (String)

Returns:

  • (Boolean)


412
413
414
415
416
417
418
419
420
421
# File 'pathname.c', line 412

static VALUE
path_fnmatch(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE pattern, flags;
    if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1)
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 2, pattern, str);
    else
        return rb_funcall(rb_cFile, rb_intern("fnmatch"), 3, pattern, str, flags);
}

#freezeObject



48
49
50
51
52
53
54
# File 'pathname.c', line 48

static VALUE
path_freeze(VALUE self)
{
    rb_call_super(0, 0);
    rb_str_freeze(get_strpath(self));
    return self;
}

#ftypeObject

See File.ftype. Returns "type" of file ("file", "directory", etc).



427
428
429
430
431
# File 'pathname.c', line 427

static VALUE
path_ftype(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("ftype"), 1, get_strpath(self));
}

#grpowned?Boolean

See FileTest.grpowned?.

Returns:

  • (Boolean)


648
649
650
651
652
# File 'pathname.c', line 648

static VALUE
path_grpowned_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("grpowned?"), 1, get_strpath(self));
}

#hashObject

:nodoc:



123
124
125
126
127
# File 'pathname.c', line 123

static VALUE
path_hash(VALUE self)
{
    return INT2FIX(rb_str_hash(get_strpath(self)));
}

#inspectObject

:nodoc:



145
146
147
148
149
150
151
# File 'pathname.c', line 145

static VALUE
path_inspect(VALUE self)
{
    const char *c = rb_obj_classname(self);
    VALUE str = get_strpath(self);
    return rb_sprintf("#<%s:%s>", c, RSTRING_PTR(str));
}

#join(*args) ⇒ Object

Pathname#join joins pathnames.

path0.join(path1, ..., pathN) is the same as path0 + path1 + ... + pathN.



360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/pathname.rb', line 360

def join(*args)
  args.unshift self
  result = args.pop
  result = Pathname.new(result) unless Pathname === result
  return result if result.absolute?
  args.reverse_each {|arg|
    arg = Pathname.new(arg) unless Pathname === arg
    result = arg + result
    return result if result.absolute?
  }
  result
end

#lchmodObject

See File.lchmod.



380
381
382
383
384
# File 'pathname.c', line 380

static VALUE
path_lchmod(VALUE self, VALUE mode)
{
    return rb_funcall(rb_cFile, rb_intern("lchmod"), 2, mode, get_strpath(self));
}

#lchownObject

See File.lchown.



398
399
400
401
402
# File 'pathname.c', line 398

static VALUE
path_lchown(VALUE self, VALUE owner, VALUE group)
{
    return rb_funcall(rb_cFile, rb_intern("lchown"), 3, owner, group, get_strpath(self));
}

#lstatObject

See File.lstat.



496
497
498
499
500
# File 'pathname.c', line 496

static VALUE
path_lstat(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("lstat"), 1, get_strpath(self));
}

See File.link. Creates a hard link at pathname.



439
440
441
442
443
# File 'pathname.c', line 439

static VALUE
path_make_link(VALUE self, VALUE old)
{
    return rb_funcall(rb_cFile, rb_intern("link"), 2, old, get_strpath(self));
}

See File.symlink. Creates a symbolic link.



508
509
510
511
512
# File 'pathname.c', line 508

static VALUE
path_make_symlink(VALUE self, VALUE old)
{
    return rb_funcall(rb_cFile, rb_intern("symlink"), 2, old, get_strpath(self));
}

#mkdirObject

See Dir.mkdir. Create the referenced directory.



887
888
889
890
891
892
893
894
895
896
# File 'pathname.c', line 887

static VALUE
path_mkdir(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE vmode;
    if (rb_scan_args(argc, argv, "01", &vmode) == 0)
        return rb_funcall(rb_cDir, rb_intern("mkdir"), 1, str);
    else
        return rb_funcall(rb_cDir, rb_intern("mkdir"), 2, str, vmode);
}

#mkpathObject

See FileUtils.mkpath. Creates a full path, including any intermediate directories that don't yet exist.



512
513
514
515
516
# File 'lib/pathname.rb', line 512

def mkpath
  require 'fileutils'
  FileUtils.mkpath(@path)
  nil
end

#mountpoint?Boolean

#mountpoint? returns true if self points to a mountpoint.

Returns:

  • (Boolean)


190
191
192
193
194
195
196
197
198
199
# File 'lib/pathname.rb', line 190

def mountpoint?
  begin
    stat1 = self.lstat
    stat2 = self.parent.lstat
    stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
      stat1.dev != stat2.dev
  rescue Errno::ENOENT
    false
  end
end

#mtimeObject

See File.mtime. Returns last modification time.



362
363
364
365
366
# File 'pathname.c', line 362

static VALUE
path_mtime(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("mtime"), 1, get_strpath(self));
}

#openObject

See File.open. Opens the file for reading or writing.



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# File 'pathname.c', line 448

static VALUE
path_open(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    if (rb_block_given_p()) {
        return rb_block_call(rb_cFile, rb_intern("open"), 1+n, args, 0, 0);
    }
    else {
        return rb_funcall2(rb_cFile, rb_intern("open"), 1+n, args);
    }
}

#opendirObject

See Dir.open.



910
911
912
913
914
915
916
917
# File 'pathname.c', line 910

static VALUE
path_opendir(VALUE self)
{
    VALUE args[1];

    args[0] = get_strpath(self);
    return rb_block_call(rb_cDir, rb_intern("open"), 1, args, 0, 0);
}

#owned?Boolean

See FileTest.owned?.

Returns:

  • (Boolean)


693
694
695
696
697
# File 'pathname.c', line 693

static VALUE
path_owned_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("owned?"), 1, get_strpath(self));
}

#parentObject

#parent returns the parent directory.

This is same as self + '..'.



185
186
187
# File 'lib/pathname.rb', line 185

def parent
  self + '..'
end

#pipe?Boolean

See FileTest.pipe?.

Returns:

  • (Boolean)


675
676
677
678
679
# File 'pathname.c', line 675

static VALUE
path_pipe_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("pipe?"), 1, get_strpath(self));
}

#read([length [, offset]]) ⇒ String #read([length [, offset]], open_args) ⇒ String

See IO.read. Returns all data from the file, or the first N bytes if specified.

Overloads:

  • #read([length [, offset]]) ⇒ String

    Returns:

    • (String)
  • #read([length [, offset]], open_args) ⇒ String

    Returns:

    • (String)


273
274
275
276
277
278
279
280
281
282
# File 'pathname.c', line 273

static VALUE
path_read(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    return rb_funcall2(rb_cIO, rb_intern("read"), 1+n, args);
}

#readable?Boolean

See FileTest.readable?.

Returns:

  • (Boolean)


702
703
704
705
706
# File 'pathname.c', line 702

static VALUE
path_readable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("readable?"), 1, get_strpath(self));
}

#readable_real?Boolean

See FileTest.readable_real?.

Returns:

  • (Boolean)


720
721
722
723
724
# File 'pathname.c', line 720

static VALUE
path_readable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("readable_real?"), 1, get_strpath(self));
}

#readlines(sep = $/[, open_args]) ⇒ Array #readlines(limit[, open_args]) ⇒ Array #readlines(sep, limit[, open_args]) ⇒ Array

See IO.readlines. Returns all the lines from the file.

Overloads:

  • #readlines(sep = $/[, open_args]) ⇒ Array

    Returns:

    • (Array)
  • #readlines(limit[, open_args]) ⇒ Array

    Returns:

    • (Array)
  • #readlines(sep, limit[, open_args]) ⇒ Array

    Returns:

    • (Array)


312
313
314
315
316
317
318
319
320
321
# File 'pathname.c', line 312

static VALUE
path_readlines(int argc, VALUE *argv, VALUE self)
{
    VALUE args[4];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
    return rb_funcall2(rb_cIO, rb_intern("readlines"), 1+n, args);
}

See File.readlink. Read symbolic link.



467
468
469
470
471
472
473
# File 'pathname.c', line 467

static VALUE
path_readlink(VALUE self)
{
    VALUE str;
    str = rb_funcall(rb_cFile, rb_intern("readlink"), 1, get_strpath(self));
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#realdirpathObject

Returns the real (absolute) pathname of self in the actual filesystem. The real pathname doesn't contain symlinks or useless dots.

The last component of the real pathname can be nonexistent.



226
227
228
229
230
231
232
233
# File 'pathname.c', line 226

static VALUE
path_realdirpath(int argc, VALUE *argv, VALUE self)
{
    VALUE basedir, str;
    rb_scan_args(argc, argv, "01", &basedir);
    str = rb_funcall(rb_cFile, rb_intern("realdirpath"), 2, get_strpath(self), basedir);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#realpathObject

Returns the real (absolute) pathname of self in the actual filesystem not containing symlinks or useless dots.

All components of the pathname must exist when this method is called.



211
212
213
214
215
216
217
218
# File 'pathname.c', line 211

static VALUE
path_realpath(int argc, VALUE *argv, VALUE self)
{
    VALUE basedir, str;
    rb_scan_args(argc, argv, "01", &basedir);
    str = rb_funcall(rb_cFile, rb_intern("realpath"), 2, get_strpath(self), basedir);
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#relative?Boolean

The opposite of #absolute?

Returns:

  • (Boolean)


219
220
221
222
223
224
225
# File 'lib/pathname.rb', line 219

def relative?
  path = @path
  while r = chop_basename(path)
    path, = r
  end
  path == ''
end

#relative_path_from(base_directory) ⇒ Object

#relative_path_from 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.

#relative_path_from doesn't access the filesystem. It assumes no symlinks.

ArgumentError is raised when it cannot find a relative path.

This method has existed since 1.8.1.



449
450
451
452
453
454
455
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
# File 'lib/pathname.rb', line 449

def relative_path_from(base_directory)
  dest_directory = self.cleanpath.to_s
  base_directory = base_directory.cleanpath.to_s
  dest_prefix = dest_directory
  dest_names = []
  while r = chop_basename(dest_prefix)
    dest_prefix, basename = r
    dest_names.unshift basename if basename != '.'
  end
  base_prefix = base_directory
  base_names = []
  while r = chop_basename(base_prefix)
    base_prefix, basename = r
    base_names.unshift basename if basename != '.'
  end
  unless SAME_PATHS[dest_prefix, base_prefix]
    raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
  end
  while !dest_names.empty? &&
        !base_names.empty? &&
        SAME_PATHS[dest_names.first, base_names.first]
    dest_names.shift
    base_names.shift
  end
  if base_names.include? '..'
    raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
  end
  base_names.fill('..')
  relpath_names = base_names + dest_names
  if relpath_names.empty?
    Pathname.new('.')
  else
    Pathname.new(File.join(*relpath_names))
  end
end

#renameObject

See File.rename. Rename the file.



478
479
480
481
482
# File 'pathname.c', line 478

static VALUE
path_rename(VALUE self, VALUE to)
{
    return rb_funcall(rb_cFile, rb_intern("rename"), 2, get_strpath(self), to);
}

#rmdirObject

See Dir.rmdir. Remove the referenced directory.



901
902
903
904
905
# File 'pathname.c', line 901

static VALUE
path_rmdir(VALUE self)
{
    return rb_funcall(rb_cDir, rb_intern("rmdir"), 1, get_strpath(self));
}

#rmtreeObject

See FileUtils.rm_r. Deletes a directory and all beneath it.



519
520
521
522
523
524
525
# File 'lib/pathname.rb', line 519

def rmtree
  # The name "rmtree" is borrowed from File::Path of Perl.
  # File::Path provides "mkpath" and "rmtree".
  require 'fileutils'
  FileUtils.rm_r(@path)
  nil
end

#root?Boolean

#root? is a predicate for root directories. I.e. it returns true if the pathname consists of consecutive slashes.

It doesn't access actual filesystem. So it may return false for some pathnames which points to roots such as /usr/...

Returns:

  • (Boolean)


208
209
210
# File 'lib/pathname.rb', line 208

def root?
  !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
end

#setgid?Boolean

See FileTest.setgid?.

Returns:

  • (Boolean)


738
739
740
741
742
# File 'pathname.c', line 738

static VALUE
path_setgid_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("setgid?"), 1, get_strpath(self));
}

#setuid?Boolean

See FileTest.setuid?.

Returns:

  • (Boolean)


729
730
731
732
733
# File 'pathname.c', line 729

static VALUE
path_setuid_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("setuid?"), 1, get_strpath(self));
}

#sizeObject

See FileTest.size.



747
748
749
750
751
# File 'pathname.c', line 747

static VALUE
path_size(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("size"), 1, get_strpath(self));
}

#size?Boolean

See FileTest.size?.

Returns:

  • (Boolean)


756
757
758
759
760
# File 'pathname.c', line 756

static VALUE
path_size_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("size?"), 1, get_strpath(self));
}

#socket?Boolean

See FileTest.socket?.

Returns:

  • (Boolean)


684
685
686
687
688
# File 'pathname.c', line 684

static VALUE
path_socket_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("socket?"), 1, get_strpath(self));
}

#splitObject

See File.split. Returns the #dirname and the #basename in an Array.



586
587
588
589
590
591
592
593
594
595
596
597
598
# File 'pathname.c', line 586

static VALUE
path_split(VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE ary, dirname, basename;
    ary = rb_funcall(rb_cFile, rb_intern("split"), 1, str);
    ary = rb_check_array_type(ary);
    dirname = rb_ary_entry(ary, 0);
    basename = rb_ary_entry(ary, 1);
    dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self));
    basename = rb_class_new_instance(1, &basename, rb_obj_class(self));
    return rb_ary_new3(2, dirname, basename);
}

#statObject

See File.stat. Returns a File::Stat object.



487
488
489
490
491
# File 'pathname.c', line 487

static VALUE
path_stat(VALUE self)
{
    return rb_funcall(rb_cFile, rb_intern("stat"), 1, get_strpath(self));
}

#sticky?Boolean

See FileTest.sticky?.

Returns:

  • (Boolean)


765
766
767
768
769
# File 'pathname.c', line 765

static VALUE
path_sticky_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("sticky?"), 1, get_strpath(self));
}

#subObject

Return a pathname which is substituted by String#sub.



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'pathname.c', line 156

static VALUE
path_sub(int argc, VALUE *argv, VALUE self)
{
    VALUE str = get_strpath(self);

    if (rb_block_given_p()) {
        str = rb_block_call(str, rb_intern("sub"), argc, argv, 0, 0);
    }
    else {
        str = rb_funcall2(str, rb_intern("sub"), argc, argv);
    }
    return rb_class_new_instance(1, &str, rb_obj_class(self));
}

#sub_extObject

Return a pathname which the extension of the basename is substituted by repl.

If self has no extension part, repl is appended.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'pathname.c', line 176

static VALUE
path_sub_ext(VALUE self, VALUE repl)
{
    VALUE str = get_strpath(self);
    VALUE str2;
    long extlen;
    const char *ext;
    const char *p;

    StringValue(repl);
    p = RSTRING_PTR(str);
    ext = ruby_find_extname(p, &extlen);
    if (ext == NULL) {
        ext = p + RSTRING_LEN(str);
    }
    else if (extlen <= 1) {
        ext += extlen;
    }
    str2 = rb_str_dup(str);
    rb_str_resize(str2, ext-p);
    rb_str_append(str2, repl);
    OBJ_INFECT(str2, str);
    return rb_class_new_instance(1, &str2, rb_obj_class(self));
}

#symlink?Boolean

See FileTest.symlink?.

Returns:

  • (Boolean)


774
775
776
777
778
# File 'pathname.c', line 774

static VALUE
path_symlink_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("symlink?"), 1, get_strpath(self));
}

#sysopen([mode, [perm]]) ⇒ Fixnum

See IO.sysopen.

Returns:

  • (Fixnum)


330
331
332
333
334
335
336
337
338
339
# File 'pathname.c', line 330

static VALUE
path_sysopen(int argc, VALUE *argv, VALUE self)
{
    VALUE args[3];
    int n;

    args[0] = get_strpath(self);
    n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
    return rb_funcall2(rb_cIO, rb_intern("sysopen"), 1+n, args);
}

#taintObject



56
57
58
59
60
61
62
# File 'pathname.c', line 56

static VALUE
path_taint(VALUE self)
{
    rb_call_super(0, 0);
    rb_obj_taint(get_strpath(self));
    return self;
}

#to_sString #to_pathString

Return the path as a String.

to_path is implemented so Pathname objects are usable with File.open, etc.

Overloads:

  • #to_sString

    Returns:

    • (String)
  • #to_pathString

    Returns:

    • (String)


138
139
140
141
142
# File 'pathname.c', line 138

static VALUE
path_to_s(VALUE self)
{
    return rb_obj_dup(get_strpath(self));
}

#to_sString #to_pathString

Return the path as a String.

to_path is implemented so Pathname objects are usable with File.open, etc.

Overloads:

  • #to_sString

    Returns:

    • (String)
  • #to_pathString

    Returns:

    • (String)


138
139
140
141
142
# File 'pathname.c', line 138

static VALUE
path_to_s(VALUE self)
{
    return rb_obj_dup(get_strpath(self));
}

#truncateObject

See File.truncate. Truncate the file to length bytes.



517
518
519
520
521
# File 'pathname.c', line 517

static VALUE
path_truncate(VALUE self, VALUE length)
{
    return rb_funcall(rb_cFile, rb_intern("truncate"), 2, get_strpath(self), length);
}

Removes a file or directory, using File.unlink or Dir.unlink as necessary.



956
957
958
959
960
961
962
# File 'pathname.c', line 956

static VALUE
path_unlink(VALUE self)
{
    VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR"));
    VALUE str = get_strpath(self);
    return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
}

#untaintObject



64
65
66
67
68
69
70
# File 'pathname.c', line 64

static VALUE
path_untaint(VALUE self)
{
    rb_call_super(0, 0);
    rb_obj_untaint(get_strpath(self));
    return self;
}

#utimeObject

See File.utime. Update the access and modification times.



526
527
528
529
530
# File 'pathname.c', line 526

static VALUE
path_utime(VALUE self, VALUE atime, VALUE mtime)
{
    return rb_funcall(rb_cFile, rb_intern("utime"), 3, atime, mtime, get_strpath(self));
}

#world_readable?Boolean

See FileTest.world_readable?.

Returns:

  • (Boolean)


711
712
713
714
715
# File 'pathname.c', line 711

static VALUE
path_world_readable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("world_readable?"), 1, get_strpath(self));
}

#world_writable?Boolean

See FileTest.world_writable?.

Returns:

  • (Boolean)


792
793
794
795
796
# File 'pathname.c', line 792

static VALUE
path_world_writable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("world_writable?"), 1, get_strpath(self));
}

#writable?Boolean

See FileTest.writable?.

Returns:

  • (Boolean)


783
784
785
786
787
# File 'pathname.c', line 783

static VALUE
path_writable_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("writable?"), 1, get_strpath(self));
}

#writable_real?Boolean

See FileTest.writable_real?.

Returns:

  • (Boolean)


801
802
803
804
805
# File 'pathname.c', line 801

static VALUE
path_writable_real_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("writable_real?"), 1, get_strpath(self));
}

#zero?Boolean

See FileTest.zero?.

Returns:

  • (Boolean)


810
811
812
813
814
# File 'pathname.c', line 810

static VALUE
path_zero_p(VALUE self)
{
    return rb_funcall(rb_mFileTest, rb_intern("zero?"), 1, get_strpath(self));
}