Class: File::Stat
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
::Comparable
|
|
| Inherits: | Object |
| Defined in: | file.c, file.c |
Overview
A File::Stat object contains information about an entry in the file system.
Each of these methods returns a new File::Stat object:
Snapshot
A new File::Stat object takes an immediate "snapshot" of the entry's information; the captured information is never updated, regardless of changes in the actual entry:
The entry must exist when .new is called:
filepath = 't.tmp'
File.exist?(filepath) # => false
File::Stat.new(filepath) # Raises Errno::ENOENT: No such file or directory.
File.write(filepath, 'foo') # Create the file.
stat = File::Stat.new(filepath) # Okay.
Later changes to the actual entry do not change the File::Stat object:
File.atime(filepath) # => 2026-04-01 11:51:38.0014518 -0500
stat.atime # => 2026-04-01 11:51:38.0014518 -0500
File.write(filepath, 'bar')
File.atime(filepath) # => 2026-04-01 11:58:11.922614 -0500
stat.atime # => 2026-04-01 11:51:38.0014518 -0500
File.delete(filepath)
stat.atime # => 2026-04-01 11:51:38.0014518 -0500
OS-Dependencies
Methods in a File::Stat object may return platform-dependents values,
and not all values are meaningful on all systems;
for example, #blocks returns nil on Windows,
but returns an integer on Linux.
See also Kernel.test.
Class Method Summary
-
.new(file_name) ⇒ Stat
constructor
Create a
Statobject for the given file name (raising an exception if the file doesn't exist).
Instance Attribute Summary
-
#blockdev? ⇒ Boolean
readonly
Returns
trueif the file is a block device,falseif it isn't or if the operating system doesn't support this feature. -
#chardev? ⇒ Boolean
readonly
Returns
trueif the file is a character device,falseif it isn't or if the operating system doesn't support this feature. -
#directory? ⇒ Boolean
readonly
Returns
trueif stat is a directory,falseotherwise. -
#executable? ⇒ Boolean
readonly
Returns
trueif stat is executable or if the operating system doesn't distinguish executable files from nonexecutable files. -
#executable_real? ⇒ Boolean
readonly
Same as #executable?, but tests using the real owner of the process.
-
#file? ⇒ Boolean
readonly
Returns
trueif stat is a regular file (not a device file, pipe, socket, etc.). -
#grpowned? ⇒ Boolean
readonly
Returns true if the effective group id of the process is the same as the group id of stat.
-
#owned? ⇒ Boolean
readonly
Returns
trueif the effective user id of the process is the same as the owner of stat. -
#pipe? ⇒ Boolean
readonly
Returns
trueif the operating system supports pipes and stat is a pipe;falseotherwise. -
#readable? ⇒ Boolean
readonly
Returns
trueif stat is readable by the effective user id of this process. -
#readable_real? ⇒ Boolean
readonly
Returns
trueif stat is readable by the real user id of this process. -
#setgid? ⇒ Boolean
readonly
Returns
trueif stat has the set-group-id permission bit set,falseif it doesn't or if the operating system doesn't support this feature. -
#setuid? ⇒ Boolean
readonly
Returns
trueif stat has the set-user-id permission bit set,falseif it doesn't or if the operating system doesn't support this feature. -
#size ⇒ Integer
readonly
Returns the size of stat in bytes.
-
#size? ⇒ Boolean
readonly
Returns
nilif stat is a zero-length file, the size of the file otherwise. -
#socket? ⇒ Boolean
readonly
Returns
trueif stat is a socket,falseif it isn't or if the operating system doesn't support this feature. -
#sticky? ⇒ Boolean
readonly
Returns
trueif stat has its sticky bit set,falseif it doesn't or if the operating system doesn't support this feature. -
#symlink? ⇒ Boolean
readonly
Returns
trueif stat is a symbolic link,falseif it isn't or if the operating system doesn't support this feature. -
#world_readable? ⇒ Boolean
readonly
If stat is readable by others, returns an integer representing the file permission bits of stat.
-
#world_writable? ⇒ Boolean
readonly
If stat is writable by others, returns an integer representing the file permission bits of stat.
-
#writable? ⇒ Boolean
readonly
Returns
trueif stat is writable by the effective user id of this process. -
#writable_real? ⇒ Boolean
readonly
Returns
trueif stat is writable by the real user id of this process. -
#zero? ⇒ Boolean
readonly
Returns
trueif stat is a zero-length file;falseotherwise.
Instance Method Summary
-
#<=>(other) ⇒ 1, ...
Compares
selfandother, by comparing their modification times; that is, by comparing self.mtime and other.mtime. - #atime ⇒ Time
-
#birthtime ⇒ Time
Returns the birth time for stat.
-
#blksize ⇒ Integer?
Returns the native file system's block size.
-
#blocks ⇒ Integer?
Returns the number of native file system blocks allocated for this file, or
nilif the operating system doesn't support this feature. -
#ctime ⇒ Time
Returns the change time for stat (that is, the time directory information about the file was changed, not the file itself).
-
#dev ⇒ Integer
Returns an integer representing the device on which stat resides.
-
#dev_major ⇒ Integer
Returns the major part of
File_Stat#devornil. -
#dev_minor ⇒ Integer
Returns the minor part of
File_Stat#devornil. -
#ftype ⇒ String
Identifies the type of stat.
-
#gid ⇒ Integer
Returns the numeric group id of the owner of stat.
-
#ino ⇒ Integer
Returns the inode number for stat.
-
#inspect ⇒ String
Produce a nicely formatted description of stat.
-
#mode ⇒ Integer
Returns an integer representing the permission bits of stat.
-
#mtime ⇒ Time
Returns the modification time of stat.
-
#nlink ⇒ Integer
Returns the number of hard links to stat.
-
#rdev ⇒ Integer?
Returns an integer representing the device type on which stat resides.
-
#rdev_major ⇒ Integer
Returns the major part of
File_Stat#rdevornil. -
#rdev_minor ⇒ Integer
Returns the minor part of
File_Stat#rdevornil. -
#uid ⇒ Integer
Returns the numeric user id of the owner of stat.
- #initialize_copy(orig) Internal use only
::Comparable - Included
| #< | Returns whether |
| #<= | Returns whether |
| #== | Compares two objects based on the receiver's #<=> method, returning true if it returns 0. |
| #> | Returns whether |
| #>= | Returns whether |
| #between? | |
| #clamp |
Constructor Details
.new(file_name) ⇒ Stat
Create a Stat object for the given file name (raising an
exception if the file doesn't exist).
# File 'file.c', line 6057
static VALUE
rb_stat_init(VALUE obj, VALUE fname)
{
rb_io_stat_data st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (STATX(StringValueCStr(fname), &st, STATX_ALL) == -1) {
rb_sys_fail_path(fname);
}
struct rb_stat *rb_st;
TypedData_Get_Struct(obj, struct rb_stat, &stat_data_type, rb_st);
rb_st->stat = st;
rb_st->initialized = true;
return Qnil;
}
Instance Attribute Details
#blockdev? ⇒ Boolean (readonly)
# File 'file.c', line 6209
static VALUE
rb_stat_b(VALUE obj)
{
#ifdef S_ISBLK
if (S_ISBLK(get_stat(obj)->ST_(mode))) return Qtrue;
#endif
return Qfalse;
}
#chardev? ⇒ Boolean (readonly)
# File 'file.c', line 6231
static VALUE
rb_stat_c(VALUE obj)
{
if (S_ISCHR(get_stat(obj)->ST_(mode))) return Qtrue;
return Qfalse;
}
#directory? ⇒ Boolean (readonly)
Returns true if stat is a directory,
false otherwise.
File.stat("testfile").directory? #=> false
File.stat(".").directory? #=> true
# File 'file.c', line 6124
static VALUE
rb_stat_d(VALUE obj)
{
if (S_ISDIR(get_stat(obj)->ST_(mode))) return Qtrue;
return Qfalse;
}
#executable? ⇒ Boolean (readonly)
Returns true if stat is executable or if the
operating system doesn't distinguish executable files from
nonexecutable files. The tests are made using the effective owner of
the process.
File.stat("testfile").executable? #=> false
# File 'file.c', line 6481
static VALUE
rb_stat_x(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (geteuid() == 0) {
return RBOOL(st->ST_(mode) & S_IXUGO);
}
#endif
#ifdef S_IXUSR
if (rb_stat_owned(obj))
return RBOOL(st->ST_(mode) & S_IXUSR);
#endif
#ifdef S_IXGRP
if (rb_stat_grpowned(obj))
return RBOOL(st->ST_(mode) & S_IXGRP);
#endif
#ifdef S_IXOTH
if (!(st->ST_(mode) & S_IXOTH)) return Qfalse;
#endif
return Qtrue;
}
#executable_real? ⇒ Boolean (readonly)
Same as #executable?, but tests using the real owner of the process.
# File 'file.c', line 6513
static VALUE
rb_stat_X(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (getuid() == 0) {
return RBOOL(st->ST_(mode) & S_IXUGO);
}
#endif
#ifdef S_IXUSR
if (rb_stat_rowned(obj))
return RBOOL(st->ST_(mode) & S_IXUSR);
#endif
#ifdef S_IXGRP
if (rb_group_member(get_stat(obj)->ST_(gid)))
return RBOOL(st->ST_(mode) & S_IXGRP);
#endif
#ifdef S_IXOTH
if (!(st->ST_(mode) & S_IXOTH)) return Qfalse;
#endif
return Qtrue;
}
#file? ⇒ Boolean (readonly)
# File 'file.c', line 6548
static VALUE
rb_stat_f(VALUE obj)
{
if (S_ISREG(get_stat(obj)->ST_(mode))) return Qtrue;
return Qfalse;
}
#grpowned? ⇒ Boolean (readonly)
# File 'file.c', line 6277
static VALUE
rb_stat_grpowned(VALUE obj)
{
#ifndef _WIN32
if (rb_group_member(get_stat(obj)->ST_(gid))) return Qtrue;
#endif
return Qfalse;
}
#owned? ⇒ Boolean (readonly)
# File 'file.c', line 6251
static VALUE
rb_stat_owned(VALUE obj)
{
if (get_stat(obj)->ST_(uid) == geteuid()) return Qtrue;
return Qfalse;
}
#pipe? ⇒ Boolean (readonly)
Returns true if the operating system supports pipes and
stat is a pipe; false otherwise.
# File 'file.c', line 6139
static VALUE
rb_stat_p(VALUE obj)
{
#ifdef S_IFIFO
if (S_ISFIFO(get_stat(obj)->ST_(mode))) return Qtrue;
#endif
return Qfalse;
}
#readable? ⇒ Boolean (readonly)
# File 'file.c', line 6297
static VALUE
rb_stat_r(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (geteuid() == 0) return Qtrue;
#endif
#ifdef S_IRUSR
if (rb_stat_owned(obj))
return RBOOL(st->ST_(mode) & S_IRUSR);
#endif
#ifdef S_IRGRP
if (rb_stat_grpowned(obj))
return RBOOL(st->ST_(mode) & S_IRGRP);
#endif
#ifdef S_IROTH
if (!(st->ST_(mode) & S_IROTH)) return Qfalse;
#endif
return Qtrue;
}
#readable_real? ⇒ Boolean (readonly)
Returns true if stat is readable by the real
user id of this process.
File.stat("testfile").readable_real? #=> true
# File 'file.c', line 6330
static VALUE
rb_stat_R(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (getuid() == 0) return Qtrue;
#endif
#ifdef S_IRUSR
if (rb_stat_rowned(obj))
return RBOOL(st->ST_(mode) & S_IRUSR);
#endif
#ifdef S_IRGRP
if (rb_group_member(get_stat(obj)->ST_(gid)))
return RBOOL(st->ST_(mode) & S_IRGRP);
#endif
#ifdef S_IROTH
if (!(st->ST_(mode) & S_IROTH)) return Qfalse;
#endif
return Qtrue;
}
#setgid? ⇒ Boolean (readonly)
# File 'file.c', line 6626
static VALUE
rb_stat_sgid(VALUE obj)
{
#ifdef S_ISGID
if (get_stat(obj)->ST_(mode) & S_ISGID) return Qtrue;
#endif
return Qfalse;
}
#setuid? ⇒ Boolean (readonly)
# File 'file.c', line 6605
static VALUE
rb_stat_suid(VALUE obj)
{
#ifdef S_ISUID
if (get_stat(obj)->ST_(mode) & S_ISUID) return Qtrue;
#endif
return Qfalse;
}
#size ⇒ Integer (readonly)
[ GitHub ]# File 'file.c', line 939
static VALUE
rb_stat_size(VALUE self)
{
return OFFT2NUM(get_stat(self)->ST_(size));
}
#size? ⇒ Boolean (readonly)
# File 'file.c', line 6585
static VALUE
rb_stat_s(VALUE obj)
{
rb_off_t size = get_stat(obj)->ST_(size);
if (size == 0) return Qnil;
return OFFT2NUM(size);
}
#socket? ⇒ Boolean (readonly)
# File 'file.c', line 6186
static VALUE
rb_stat_S(VALUE obj)
{
#ifdef S_ISSOCK
if (S_ISSOCK(get_stat(obj)->ST_(mode))) return Qtrue;
#endif
return Qfalse;
}
#sticky? ⇒ Boolean (readonly)
# File 'file.c', line 6647
static VALUE
rb_stat_sticky(VALUE obj)
{
#ifdef S_ISVTX
if (get_stat(obj)->ST_(mode) & S_ISVTX) return Qtrue;
#endif
return Qfalse;
}
#symlink? ⇒ Boolean (readonly)
Returns true if stat is a symbolic link,
false if it isn't or if the operating system doesn't
support this feature. As File.stat automatically follows symbolic
links, #symlink? will always be false for an object
returned by File.stat.
File.symlink("testfile", "alink") #=> 0
File.stat("alink").symlink? #=> false
File.lstat("alink").symlink? #=> true
# File 'file.c', line 6165
static VALUE
rb_stat_l(VALUE obj)
{
#ifdef S_ISLNK
if (S_ISLNK(get_stat(obj)->ST_(mode))) return Qtrue;
#endif
return Qfalse;
}
#world_readable? ⇒ Boolean (readonly)
If stat is readable by others, returns an integer
representing the file permission bits of stat. Returns
nil otherwise. The meaning of the bits is platform
dependent; on Unix systems, see stat(2).
m = File.stat("/etc/passwd").world_readable? #=> 420
sprintf("%o", m) #=> "644"
# File 'file.c', line 6365
static VALUE
rb_stat_wr(VALUE obj)
{
#ifdef S_IROTH
rb_io_stat_data *st = get_stat(obj);
if ((st->ST_(mode) & (S_IROTH)) == S_IROTH) {
return UINT2NUM(st->ST_(mode) & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
}
#world_writable? ⇒ Boolean (readonly)
If stat is writable by others, returns an integer
representing the file permission bits of stat. Returns
nil otherwise. The meaning of the bits is platform
dependent; on Unix systems, see stat(2).
m = File.stat("/tmp").world_writable? #=> 511
sprintf("%o", m) #=> "777"
# File 'file.c', line 6456
static VALUE
rb_stat_ww(VALUE obj)
{
#ifdef S_IWOTH
rb_io_stat_data *st = get_stat(obj);
if ((st->ST_(mode) & (S_IWOTH)) == S_IWOTH) {
return UINT2NUM(st->ST_(mode) & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
}
#writable? ⇒ Boolean (readonly)
# File 'file.c', line 6388
static VALUE
rb_stat_w(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (geteuid() == 0) return Qtrue;
#endif
#ifdef S_IWUSR
if (rb_stat_owned(obj))
return RBOOL(st->ST_(mode) & S_IWUSR);
#endif
#ifdef S_IWGRP
if (rb_stat_grpowned(obj))
return RBOOL(st->ST_(mode) & S_IWGRP);
#endif
#ifdef S_IWOTH
if (!(st->ST_(mode) & S_IWOTH)) return Qfalse;
#endif
return Qtrue;
}
#writable_real? ⇒ Boolean (readonly)
Returns true if stat is writable by the real
user id of this process.
File.stat("testfile").writable_real? #=> true
# File 'file.c', line 6421
static VALUE
rb_stat_W(VALUE obj)
{
rb_io_stat_data *st = get_stat(obj);
#ifdef USE_GETEUID
if (getuid() == 0) return Qtrue;
#endif
#ifdef S_IWUSR
if (rb_stat_rowned(obj))
return RBOOL(st->ST_(mode) & S_IWUSR);
#endif
#ifdef S_IWGRP
if (rb_group_member(get_stat(obj)->ST_(gid)))
return RBOOL(st->ST_(mode) & S_IWGRP);
#endif
#ifdef S_IWOTH
if (!(st->ST_(mode) & S_IWOTH)) return Qfalse;
#endif
return Qtrue;
}
#zero? ⇒ Boolean (readonly)
[ GitHub ]
# File 'file.c', line 6566
static VALUE
rb_stat_z(VALUE obj)
{
if (get_stat(obj)->ST_(size) == 0) return Qtrue;
return Qfalse;
}
Instance Method Details
#<=>(other) ⇒ 1, ...
Compares self and other, by comparing their modification times;
that is, by comparing self.mtime and other.mtime.
Returns:
-1, if self.mtime is earlier.0, if the two values are equal.1, if self.mtime is later.nil, ifotheris not aStatobject.
Examples:
stat0 = File.stat('README.md')
stat1 = File.stat('NEWS.md')
stat0.mtime # => 2025-12-20 15:33:05.6972341 -0600
stat1.mtime # => 2025-12-20 16:02:08.2672945 -0600
stat0 <=> stat1 # => -1
stat0 <=> stat0.dup # => 0
stat1 <=> stat0 # => 1
stat0 <=> :foo # => nil
Class File::Stat includes module ::Comparable,
each of whose methods uses <=> for comparison.
# File 'file.c', line 656
static VALUE
rb_stat_cmp(VALUE self, VALUE other)
{
if (rb_obj_is_kind_of(other, rb_obj_class(self))) {
stat_timestamp ts1 = statx_mtimespec(get_stat(self));
stat_timestamp ts2 = statx_mtimespec(get_stat(other));
if (ts1.tv_sec == ts2.tv_sec) {
if (ts1.tv_nsec == ts2.tv_nsec) return INT2FIX(0);
if (ts1.tv_nsec < ts2.tv_nsec) return INT2FIX(-1);
return INT2FIX(1);
}
if (ts1.tv_sec < ts2.tv_sec) return INT2FIX(-1);
return INT2FIX(1);
}
return Qnil;
}
#atime ⇒ Time
Returns a new ::Time object containing the access time
of the object represented by self
at the time self was created;
see Snapshot:
filepath = 't.tmp'
File.write(filepath, 'foo')
file = File.new(filepath, 'w')
stat = File::Stat.new(filepath)
file.atime # => 2026-03-31 16:26:39.5913207 -0500
stat.atime # => 2026-03-31 16:26:39.5913207 -0500
File.write(filepath, 'bar')
file.atime # => 2026-03-31 16:27:01.4981624 -0500 # Changed by access.
stat.atime # => 2026-03-31 16:26:39.5913207 -0500 # Unchanged by access.
stat = File::Stat.new(filepath)
stat.atime # => 2026-03-31 16:27:01.4981624 -0500 # New access time.
file.close
File.delete(filepath)
# File 'file.c', line 1127
static VALUE
rb_stat_atime(VALUE self)
{
return stat_time(statx_atimespec(get_stat(self)));
}
#birthtime ⇒ Time
Returns the birth time for stat.
If the platform doesn't have birthtime, raises ::NotImplementedError.
File.write("testfile", "foo")
sleep 10
File.write("testfile", "bar")
sleep 10
File.chmod(0644, "testfile")
sleep 10
File.read("testfile")
File.stat("testfile").birthtime #=> 2014-02-24 11:19:17 +0900
File.stat("testfile").mtime #=> 2014-02-24 11:19:27 +0900
File.stat("testfile").ctime #=> 2014-02-24 11:19:37 +0900
File.stat("testfile").atime #=> 2014-02-24 11:19:47 +0900
# File 'file.c', line 1192
static VALUE
rb_stat_birthtime(VALUE self)
{
return statx_birthtime(get_stat(self));
}
#blksize ⇒ Integer?
# File 'file.c', line 956
static VALUE
rb_stat_blksize(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
return ULONG2NUM(get_stat(self)->ST_(blksize));
#else
return Qnil;
#endif
}
#blocks ⇒ Integer?
# File 'file.c', line 977
static VALUE
rb_stat_blocks(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
# if SIZEOF_STRUCT_STAT_ST_BLOCKS > SIZEOF_LONG
return ULL2NUM(get_stat(self)->ST_(blocks));
# else
return ULONG2NUM(get_stat(self)->ST_(blocks));
# endif
#else
return Qnil;
#endif
}
#ctime ⇒ Time
# File 'file.c', line 1163
static VALUE
rb_stat_ctime(VALUE self)
{
return stat_time(statx_ctimespec(get_stat(self)));
}
#dev ⇒ Integer
[ GitHub ]# File 'file.c', line 695
static VALUE
rb_stat_dev(VALUE self)
{
#if RUBY_USE_STATX
unsigned int m = get_stat(self)->stx_dev_major;
unsigned int n = get_stat(self)->stx_dev_minor;
return ULL2NUM(makedev(m, n));
#elif SIZEOF_STRUCT_STAT_ST_DEV <= SIZEOF_DEV_T
return DEVT2NUM(get_stat(self)->st_dev);
#elif SIZEOF_STRUCT_STAT_ST_DEV <= SIZEOF_LONG
return ULONG2NUM(get_stat(self)->st_dev);
#else
return ULL2NUM(get_stat(self)->st_dev);
#endif
}
#dev_major ⇒ Integer
# File 'file.c', line 722
static VALUE
rb_stat_dev_major(VALUE self)
{
#if RUBY_USE_STATX
return UINT2NUM(get_stat(self)->stx_dev_major);
#elif defined(major)
return UINT2NUM(major(get_stat(self)->st_dev));
#else
return Qnil;
#endif
}
#dev_minor ⇒ Integer
# File 'file.c', line 745
static VALUE
rb_stat_dev_minor(VALUE self)
{
#if RUBY_USE_STATX
return UINT2NUM(get_stat(self)->stx_dev_minor);
#elif defined(minor)
return UINT2NUM(minor(get_stat(self)->st_dev));
#else
return Qnil;
#endif
}
#ftype ⇒ String
# File 'file.c', line 6107
static VALUE
rb_stat_ftype(VALUE obj)
{
return rb_file_ftype(get_stat(obj)->ST_(mode));
}
#gid ⇒ Integer
[ GitHub ]# File 'file.c', line 848
static VALUE
rb_stat_gid(VALUE self)
{
return GIDT2NUM(get_stat(self)->ST_(gid));
}
#initialize_copy(orig)
# File 'file.c', line 6078
static VALUE
rb_stat_init_copy(VALUE copy, VALUE orig)
{
if (!OBJ_INIT_COPY(copy, orig)) return copy;
struct rb_stat *orig_rb_st;
TypedData_Get_Struct(orig, struct rb_stat, &stat_data_type, orig_rb_st);
struct rb_stat *copy_rb_st;
TypedData_Get_Struct(copy, struct rb_stat, &stat_data_type, copy_rb_st);
*copy_rb_st = *orig_rb_st;
return copy;
}
#ino ⇒ Integer
[ GitHub ]# File 'file.c', line 767
static VALUE
rb_stat_ino(VALUE self)
{
rb_io_stat_data *ptr = get_stat(self);
#ifdef HAVE_STRUCT_STAT_ST_INOHIGH
/* assume INTEGER_PACK_LSWORD_FIRST and st_inohigh is just next of st_ino */
return rb_integer_unpack(&ptr->st_ino, 2,
SIZEOF_STRUCT_STAT_ST_INO, 0,
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
INTEGER_PACK_2COMP);
#else
return UIANY2NUM(ptr->ST_(ino));
#endif
}
#inspect ⇒ String
Produce a nicely formatted description of stat.
File.stat("/etc/passwd").inspect
#=> "#<File::Stat dev=0xe000005, ino=1078078, mode=0100644,
# nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096,
# blocks=8, atime=Wed Dec 10 10:16:12 CST 2003,
# mtime=Fri Sep 12 15:41:41 CDT 2003,
# ctime=Mon Oct 27 11:20:27 CST 2003,
# birthtime=Mon Aug 04 08:13:49 CDT 2003>"
# File 'file.c', line 1216
static VALUE
rb_stat_inspect(VALUE self)
{
VALUE str;
size_t i;
static const struct {
const char *name;
VALUE (*func)(VALUE);
} member[] = {
{"dev", rb_stat_dev},
{"ino", rb_stat_ino},
{"mode", rb_stat_mode},
{"nlink", rb_stat_nlink},
{"uid", rb_stat_uid},
{"gid", rb_stat_gid},
{"rdev", rb_stat_rdev},
{"size", rb_stat_size},
{"blksize", rb_stat_blksize},
{"blocks", rb_stat_blocks},
{"atime", rb_stat_atime},
{"mtime", rb_stat_mtime},
{"ctime", rb_stat_ctime},
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
{"birthtime", rb_stat_birthtime},
#endif
};
struct rb_stat* rb_st;
TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
if (!rb_st->initialized) {
return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
}
str = rb_str_buf_new2("#<");
rb_str_buf_cat2(str, rb_obj_classname(self));
rb_str_buf_cat2(str, " ");
for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {
VALUE v;
if (i > 0) {
rb_str_buf_cat2(str, ", ");
}
rb_str_buf_cat2(str, member[i].name);
rb_str_buf_cat2(str, "=");
v = (*member[i].func)(self);
if (i == 2) { /* mode */
rb_str_catf(str, "0%lo", (unsigned long)NUM2ULONG(v));
}
else if (i == 0 || i == 6) { /* dev/rdev */
rb_str_catf(str, "0x%"PRI_DEVT_PREFIX"x", NUM2DEVT(v));
}
else {
rb_str_append(str, rb_inspect(v));
}
}
rb_str_buf_cat2(str, ">");
return str;
}
#mode ⇒ Integer
# File 'file.c', line 795
static VALUE
rb_stat_mode(VALUE self)
{
return UINT2NUM(ST2UINT(get_stat(self)->ST_(mode)));
}
#mtime ⇒ Time
[ GitHub ]# File 'file.c', line 1143
static VALUE
rb_stat_mtime(VALUE self)
{
return stat_time(statx_mtimespec(get_stat(self)));
}
#nlink ⇒ Integer
# File 'file.c', line 813
static VALUE
rb_stat_nlink(VALUE self)
{
/* struct stat::st_nlink is nlink_t in POSIX. Not the case for Windows. */
const rb_io_stat_data *ptr = get_stat(self);
return UIANY2NUM(ptr->ST_(nlink));
}
#rdev ⇒ Integer?
# File 'file.c', line 866
static VALUE
rb_stat_rdev(VALUE self)
{
#if RUBY_USE_STATX
unsigned int m = get_stat(self)->stx_rdev_major;
unsigned int n = get_stat(self)->stx_rdev_minor;
return ULL2NUM(makedev(m, n));
#elif !defined(HAVE_STRUCT_STAT_ST_RDEV)
return Qnil;
#elif SIZEOF_STRUCT_STAT_ST_RDEV <= SIZEOF_DEV_T
return DEVT2NUM(get_stat(self)->ST_(rdev));
#elif SIZEOF_STRUCT_STAT_ST_RDEV <= SIZEOF_LONG
return ULONG2NUM(get_stat(self)->ST_(rdev));
#else
return ULL2NUM(get_stat(self)->ST_(rdev));
#endif
}
#rdev_major ⇒ Integer
# File 'file.c', line 895
static VALUE
rb_stat_rdev_major(VALUE self)
{
#if RUBY_USE_STATX
return UINT2NUM(get_stat(self)->stx_rdev_major);
#elif defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(major)
return UINT2NUM(major(get_stat(self)->ST_(rdev)));
#else
return Qnil;
#endif
}
#rdev_minor ⇒ Integer
# File 'file.c', line 918
static VALUE
rb_stat_rdev_minor(VALUE self)
{
#if RUBY_USE_STATX
return UINT2NUM(get_stat(self)->stx_rdev_minor);
#elif defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(minor)
return UINT2NUM(minor(get_stat(self)->ST_(rdev)));
#else
return Qnil;
#endif
}
#uid ⇒ Integer
[ GitHub ]# File 'file.c', line 832
static VALUE
rb_stat_uid(VALUE self)
{
return UIDT2NUM(get_stat(self)->ST_(uid));
}