diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml
index 6378861a2111df..a1fa38be1c5056 100644
--- a/.github/workflows/annocheck.yml
+++ b/.github/workflows/annocheck.yml
@@ -67,7 +67,7 @@ jobs:
sparse-checkout: /.github
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml
index 6e0c5c6e79e889..8784f8b8fa5d9b 100644
--- a/.github/workflows/auto_review_pr.yml
+++ b/.github/workflows/auto_review_pr.yml
@@ -29,7 +29,7 @@ jobs:
with:
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.4'
bundler: none
diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml
index 9531352602b4ba..1063f0c6f1a821 100644
--- a/.github/workflows/baseruby.yml
+++ b/.github/workflows/baseruby.yml
@@ -48,7 +48,7 @@ jobs:
- ruby-3.3
steps:
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml
index 79b05874a0ea71..1065ce46939df1 100644
--- a/.github/workflows/bundled_gems.yml
+++ b/.github/workflows/bundled_gems.yml
@@ -38,7 +38,7 @@ jobs:
with:
token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: 4.0
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
index e98567e7fad83b..95f4e4d0cac7b8 100644
--- a/.github/workflows/check_misc.yml
+++ b/.github/workflows/check_misc.yml
@@ -23,7 +23,7 @@ jobs:
token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: head
diff --git a/.github/workflows/check_sast.yml b/.github/workflows/check_sast.yml
index d94a19fd2dbede..54fc3de435bbfb 100644
--- a/.github/workflows/check_sast.yml
+++ b/.github/workflows/check_sast.yml
@@ -78,14 +78,14 @@ jobs:
persist-credentials: false
- name: Initialize CodeQL
- uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
+ uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
languages: ${{ matrix.language }}
build-mode: none
config-file: .github/codeql/codeql-config.yml
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
+ uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
category: '/language:${{ matrix.language }}'
upload: False
@@ -127,7 +127,7 @@ jobs:
continue-on-error: true
- name: Upload SARIF
- uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
+ uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
sarif_file: sarif-results/${{ matrix.language }}.sarif
continue-on-error: true
diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml
index e74b028f091ad8..05bec2c58e42e9 100644
--- a/.github/workflows/modgc.yml
+++ b/.github/workflows/modgc.yml
@@ -67,7 +67,7 @@ jobs:
uses: ./.github/actions/setup/ubuntu
if: ${{ contains(matrix.os, 'ubuntu') }}
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml
index 138acebc5e0fc5..32a71206467517 100644
--- a/.github/workflows/parse_y.yml
+++ b/.github/workflows/parse_y.yml
@@ -59,7 +59,7 @@ jobs:
- uses: ./.github/actions/setup/ubuntu
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index f5b2344231c8b0..b67cb41eebdcb8 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -22,7 +22,7 @@ jobs:
with:
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: 3.3.4
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 9c2adf56600433..a9ada18667f77d 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -73,6 +73,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
+ uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
sarif_file: results.sarif
diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml
index 2f950b52064bd9..8393934195ff6a 100644
--- a/.github/workflows/spec_guards.yml
+++ b/.github/workflows/spec_guards.yml
@@ -49,7 +49,7 @@ jobs:
with:
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml
index 0adc2cd75fa655..1802371c148042 100644
--- a/.github/workflows/sync_default_gems.yml
+++ b/.github/workflows/sync_default_gems.yml
@@ -39,7 +39,7 @@ jobs:
with:
token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.4'
bundler: none
diff --git a/.github/workflows/tarball-ubuntu.yml b/.github/workflows/tarball-ubuntu.yml
index 8cb0936b81fb4b..69ac28c08cd53d 100644
--- a/.github/workflows/tarball-ubuntu.yml
+++ b/.github/workflows/tarball-ubuntu.yml
@@ -44,7 +44,7 @@ jobs:
set -x
sudo apt-get update -q
sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev zlib1g-dev libffi-dev libgmp-dev bison- autoconf-
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.2'
# test-bundled-gems requires executable host ruby
diff --git a/.github/workflows/tarball-windows.yml b/.github/workflows/tarball-windows.yml
index e1523dcc17f199..ca3c3014706ef3 100644
--- a/.github/workflows/tarball-windows.yml
+++ b/.github/workflows/tarball-windows.yml
@@ -50,7 +50,7 @@ jobs:
- run: md build
working-directory:
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.2'
bundler: none
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index 087f99f3eba1d7..9d509edcde169e 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -78,7 +78,7 @@ jobs:
with:
arch: ${{ matrix.arch }}
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml
index 01cab4d42cf8c4..987605ecca9983 100644
--- a/.github/workflows/wasm.yml
+++ b/.github/workflows/wasm.yml
@@ -65,7 +65,7 @@ jobs:
sparse-checkout: /.github
persist-credentials: false
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 1888c5ab1d1517..3ff44391fb073b 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -64,7 +64,7 @@ jobs:
- run: md build
working-directory:
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
# windows-11-arm has only 3.4.1, 3.4.2, 3.4.3, head
ruby-version: ${{ !endsWith(matrix.os, 'arm') && '3.1' || '3.4' }}
@@ -266,7 +266,7 @@ jobs:
- run: md build
working-directory:
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml
index d5dc60c629200a..2764456b75e3de 100644
--- a/.github/workflows/yjit-ubuntu.yml
+++ b/.github/workflows/yjit-ubuntu.yml
@@ -138,7 +138,7 @@ jobs:
- uses: ./.github/actions/setup/ubuntu
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml
index d3de016ff5cf07..fe0db1494ea8d4 100644
--- a/.github/workflows/zjit-macos.yml
+++ b/.github/workflows/zjit-macos.yml
@@ -98,7 +98,7 @@ jobs:
rustup install ${{ matrix.rust_version }} --profile minimal
rustup default ${{ matrix.rust_version }}
- - uses: taiki-e/install-action@26e9283f268b880168bdbd2c545dfcd60ec2c6ab # v2.87.13
+ - uses: taiki-e/install-action@9114bf4d891761788c546334fd37538eae1bf8b3 # v2.87.16
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml
index 59d5f34726dc44..d80737229d0021 100644
--- a/.github/workflows/zjit-ubuntu.yml
+++ b/.github/workflows/zjit-ubuntu.yml
@@ -147,12 +147,12 @@ jobs:
- uses: ./.github/actions/setup/ubuntu
- - uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
+ - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 # v1.324.0
with:
ruby-version: '3.1'
bundler: none
- - uses: taiki-e/install-action@26e9283f268b880168bdbd2c545dfcd60ec2c6ab # v2.87.13
+ - uses: taiki-e/install-action@9114bf4d891761788c546334fd37538eae1bf8b3 # v2.87.16
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
diff --git a/array.c b/array.c
index 95d817dca12da6..f84f7ae3b91659 100644
--- a/array.c
+++ b/array.c
@@ -7355,13 +7355,17 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
static VALUE
rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
{
- long r, n, i;
+ long r, i;
- n = RARRAY_LEN(ary); /* Array length */
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
- r = n;
- if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
r = NUM2LONG(argv[0]); /* Permutation size from argument */
+ }
+ else {
+ r = RARRAY_LEN(ary);
+ }
+
+ long n = RARRAY_LEN(ary);
if (r < 0 || n < r) {
/* no permutations: yield nothing */
diff --git a/dir.c b/dir.c
index d9536b200ba22b..221fe3fffc16c6 100644
--- a/dir.c
+++ b/dir.c
@@ -807,13 +807,35 @@ dir_fileno(VALUE dir)
#endif
/*
+ * :markup: markdown
+ *
* call-seq:
* path -> string or nil
*
- * Returns the +dirpath+ string that was used to create +self+
- * (or +nil+ if created by method Dir.for_fd):
+ * If `self` was created with a string path, returns that path:
+ *
+ * ```ruby
+ * dirpath = 'doc/tmp'
+ * Dir.mkdir(dirpath)
+ * dir = Dir.new(dirpath)
+ * dir.path # => "../ruby/doc/syntax"
+ * ```
+ *
+ * The path remains even when the directory is removed:
+ *
+ * ```ruby
+ * Dir.rmdir(dirpath)
+ * dir.path # => "../ruby/doc/syntax"
+ * ```
+ *
+ * If `self` was created with a file descriptor, returns `nil`:
*
- * Dir.new('example').path # => "example"
+ * ```
+ * dir0 = Dir.new('.')
+ * fd = dir0.fileno # => 8
+ * dir1 = Dir.for_fd(fd)
+ * dir1.path # => nil
+ * ```
*
*/
static VALUE
diff --git a/file.c b/file.c
index 9088990792f1bc..e12f26e2a918f7 100644
--- a/file.c
+++ b/file.c
@@ -719,8 +719,7 @@ rb_stat_dev(VALUE self)
* call-seq:
* stat.dev_major -> integer
*
- * Returns the major part of File_Stat#dev or
- * nil.
+ * Returns the major part of File::Stat#dev or +nil+.
*
* File.stat("/dev/fd1").dev_major #=> 2
* File.stat("/dev/tty").dev_major #=> 5
@@ -742,8 +741,7 @@ rb_stat_dev_major(VALUE self)
* call-seq:
* stat.dev_minor -> integer
*
- * Returns the minor part of File_Stat#dev or
- * nil.
+ * Returns the minor part of File::Stat#dev or +nil+.
*
* File.stat("/dev/fd1").dev_minor #=> 1
* File.stat("/dev/tty").dev_minor #=> 0
@@ -863,8 +861,8 @@ rb_stat_gid(VALUE self)
* stat.rdev -> integer or nil
*
* Returns an integer representing the device type on which
- * stat resides. Returns nil if the operating
- * system doesn't support this feature.
+ * stat resides. Returns +nil+ if the operating system doesn't
+ * support this feature.
*
* File.stat("/dev/fd1").rdev #=> 513
* File.stat("/dev/tty").rdev #=> 1280
@@ -892,8 +890,7 @@ rb_stat_rdev(VALUE self)
* call-seq:
* stat.rdev_major -> integer
*
- * Returns the major part of File_Stat#rdev or
- * nil.
+ * Returns the major part of File::Stat#rdev or +nil+.
*
* File.stat("/dev/fd1").rdev_major #=> 2
* File.stat("/dev/tty").rdev_major #=> 5
@@ -915,8 +912,7 @@ rb_stat_rdev_major(VALUE self)
* call-seq:
* stat.rdev_minor -> integer
*
- * Returns the minor part of File_Stat#rdev or
- * nil.
+ * Returns the minor part of File::Stat#rdev or +nil+.
*
* File.stat("/dev/fd1").rdev_minor #=> 1
* File.stat("/dev/tty").rdev_minor #=> 0
@@ -953,8 +949,8 @@ rb_stat_size(VALUE self)
* call-seq:
* stat.blksize -> integer or nil
*
- * Returns the native file system's block size. Will return nil
- * on platforms that don't support this information.
+ * Returns the native file system's block size. Will return +nil+ on
+ * platforms that don't support this information.
*
* File.stat("testfile").blksize #=> 4096
*
@@ -975,8 +971,8 @@ rb_stat_blksize(VALUE self)
* stat.blocks -> integer or nil
*
* Returns the number of native file system blocks allocated for this
- * file, or nil if the operating system doesn't
- * support this feature.
+ * file, or +nil+ if the operating system doesn't support this
+ * feature.
*
* File.stat("testfile").blocks #=> 2
*/
@@ -2077,6 +2073,17 @@ rb_file_chardev_p(VALUE obj, VALUE fname)
* file = File.new(filepath)
* File.exist?(file) # => true
* file.close # Clean up.
+ * File.unlink(filepath) # Clean up.
+ *
+ * Follows symbolic links:
+ *
+ * # Symbolic links.
+ * File.symlink('README.md', 'README.link')
+ * File.symlink('nosuch', 'BROKEN.link')
+ * File.exist?('README.link') # => true
+ * File.exist?('BROKEN.link') # => false
+ * File.unlink('README.link') # Clean up.
+ * File.unlink('BROKEN.link') # Clean up.
*
*/
@@ -2147,8 +2154,8 @@ rb_file_readable_real_p(VALUE obj, VALUE fname)
*
* If file_name is readable by others, returns an integer
* representing the file permission bits of file_name. Returns
- * nil otherwise. The meaning of the bits is platform
- * dependent; on Unix systems, see stat(2).
+ * +nil+ otherwise. The meaning of the bits is platform dependent; on
+ * Unix systems, see stat(2).
*
* _file_name_ can be an IO object.
*
@@ -2175,8 +2182,8 @@ rb_file_world_readable_p(VALUE obj, VALUE fname)
* call-seq:
* File.writable?(file_name) -> true or false
*
- * Returns true if the named file is writable by the effective
- * user and group id of this process. See eaccess(3).
+ * Returns +true+ if the named file is writable by the effective user and
+ * group id of this process. See eaccess(3).
*
* Note that some OS-level security features may cause this to return true
* even though the file is not writable by the effective user/group.
@@ -2192,8 +2199,8 @@ rb_file_writable_p(VALUE obj, VALUE fname)
* call-seq:
* File.writable_real?(file_name) -> true or false
*
- * Returns true if the named file is writable by the real
- * user and group id of this process. See access(3).
+ * Returns +true+ if the named file is writable by the real user and group id
+ * of this process. See access(3).
*
* Note that some OS-level security features may cause this to return true
* even though the file is not writable by the real user/group.
@@ -2211,8 +2218,8 @@ rb_file_writable_real_p(VALUE obj, VALUE fname)
*
* If file_name is writable by others, returns an integer
* representing the file permission bits of file_name. Returns
- * nil otherwise. The meaning of the bits is platform
- * dependent; on Unix systems, see stat(2).
+ * +nil+ otherwise. The meaning of the bits is platform dependent; on
+ * Unix systems, see stat(2).
*
* _file_name_ can be an IO object.
*
@@ -2279,8 +2286,8 @@ rb_file_executable_p(VALUE obj, VALUE fname)
* call-seq:
* File.executable_real?(file_name) -> true or false
*
- * Returns true if the named file is executable by the real
- * user and group id of this process. See access(3).
+ * Returns +true+ if the named file is executable by the real user and group
+ * id of this process. See access(3).
*
* Windows does not support execute permissions separately from read
* permissions. On Windows, a file is only considered executable if it ends in
@@ -2489,7 +2496,7 @@ check3rdbyte(VALUE fname, int mode)
* call-seq:
* File.setuid?(file_name) -> true or false
*
- * Returns true if the named file has the setuid bit set.
+ * Returns +true+ if the named file has the setuid bit set.
*
* _file_name_ can be an IO object.
*/
@@ -2508,7 +2515,7 @@ rb_file_suid_p(VALUE obj, VALUE fname)
* call-seq:
* File.setgid?(file_name) -> true or false
*
- * Returns true if the named file has the setgid bit set.
+ * Returns +true+ if the named file has the setgid bit set.
*
* _file_name_ can be an IO object.
*/
@@ -2527,7 +2534,7 @@ rb_file_sgid_p(VALUE obj, VALUE fname)
* call-seq:
* File.sticky?(file_name) -> true or false
*
- * Returns true if the named file has the sticky bit set.
+ * Returns +true+ if the named file has the sticky bit set.
*
* _file_name_ can be an IO object.
*/
@@ -3385,9 +3392,9 @@ rb_fchown(int fd, rb_uid_t owner, rb_gid_t group)
* Changes the owner and group of file to the given numeric
* owner and group id's. Only a process with superuser privileges may
* change the owner of a file. The current owner of a file may change
- * the file's group to any group to which the owner belongs. A
- * nil or -1 owner or group id is ignored. Follows
- * symbolic links. See also File#lchown.
+ * the file's group to any group to which the owner belongs. A +nil+
+ * or -1 owner or group id is ignored. Follows symbolic links. See
+ * also File#lchown.
*
* File.new("testfile").chown(502, 1000)
*
@@ -4111,11 +4118,10 @@ rb_file_s_rename(VALUE klass, VALUE from, VALUE to)
* File.umask() -> integer
* File.umask(integer) -> integer
*
- * Returns the current umask value for this process. If the optional
- * argument is given, set the umask to that value and return the
- * previous value. Umask values are subtracted from the
- * default permissions, so a umask of 0222 would make a
- * file read-only for everyone.
+ * Returns the current umask value for this process. If the optional argument
+ * is given, set the umask to that value and return the previous value. Umask
+ * values are subtracted from the default permissions, so a umask of
+ * +0222+ would make a file read-only for everyone.
*
* File.umask(0006) #=> 18
* File.umask #=> 6
@@ -6006,30 +6012,21 @@ rb_file_s_extname(VALUE klass, VALUE fname)
}
/*
- * call-seq:
- * File.path(path) -> string
- *
- * Returns the string representation of the path
- *
- * File.path(File::NULL) #=> "/dev/null"
- * File.path(Pathname.new("/tmp")) #=> "/tmp"
- *
- * If +path+ is not a String:
- *
- * 1. If it has the +to_path+ method, that method will be called to
- * coerce to a String.
+ * :markup: markdown
*
- * 2. Otherwise, or if the coerced result is not a String too, the
- * standard coercion using +to_str+ method will take place on that
- * object. (See also String.try_convert)
+ * call-seq:
+ * File.path(path) -> string
*
- * The coerced string must satisfy the following conditions:
+ * Returns a string representation of the given `path`:
*
- * 1. It must be in an ASCII-compatible encoding; otherwise, an
- * Encoding::CompatibilityError is raised.
+ * ```ruby
+ * File.path(File::NULL) # => "/dev/null"
+ * File.path('/tmp') # => "/tmp"
+ * File.path('../ruby') # => "../ruby"
+ * File.path($stdin) # => ""
+ * File.path('nosuch') # => "nosuch"
+ * ```
*
- * 2. It must not contain the NUL character (\0); otherwise,
- * an ArgumentError is raised.
*/
static VALUE
@@ -6833,8 +6830,7 @@ rb_stat_ftype(VALUE obj)
* call-seq:
* stat.directory? -> true or false
*
- * Returns true if stat is a directory,
- * false otherwise.
+ * Returns +true+ if stat is a directory, +false+ otherwise.
*
* File.stat("testfile").directory? #=> false
* File.stat(".").directory? #=> true
@@ -6910,9 +6906,8 @@ rb_stat_l(VALUE obj)
* call-seq:
* stat.socket? -> true or false
*
- * Returns true if stat is a socket,
- * false if it isn't or if the operating system doesn't
- * support this feature.
+ * Returns +true+ if stat is a socket, +false+ if it isn't or if the
+ * operating system doesn't support this feature.
*
* File.stat("testfile").socket? #=> false
*
@@ -6932,9 +6927,8 @@ rb_stat_S(VALUE obj)
* call-seq:
* stat.blockdev? -> true or false
*
- * Returns true if the file is a block device,
- * false if it isn't or if the operating system doesn't
- * support this feature.
+ * Returns +true+ if the file is a block device, +false+ if it isn't or if
+ * the operating system doesn't support this feature.
*
* File.stat("testfile").blockdev? #=> false
* File.stat("/dev/hda1").blockdev? #=> true
@@ -6955,9 +6949,8 @@ rb_stat_b(VALUE obj)
* call-seq:
* stat.chardev? -> true or false
*
- * Returns true if the file is a character device,
- * false if it isn't or if the operating system doesn't
- * support this feature.
+ * Returns +true+ if the file is a character device, +false+ if it isn't or
+ * if the operating system doesn't support this feature.
*
* File.stat("/dev/tty").chardev? #=> true
*
@@ -7119,9 +7112,9 @@ rb_stat_R(VALUE obj)
* stat.world_readable? -> integer or nil
*
* 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).
+ * 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"
@@ -7143,8 +7136,8 @@ rb_stat_wr(VALUE obj)
* call-seq:
* stat.writable? -> true or false
*
- * Returns true if stat is writable by the
- * effective user id of this process.
+ * Returns +true+ if stat is writable by the effective user id of this
+ * process.
*
* File.stat("testfile").writable? #=> true
*
@@ -7176,8 +7169,8 @@ rb_stat_w(VALUE obj)
* call-seq:
* stat.writable_real? -> true or false
*
- * Returns true if stat is writable by the real
- * user id of this process.
+ * Returns +true+ if stat is writable by the real user id of this
+ * process.
*
* File.stat("testfile").writable_real? #=> true
*
@@ -7210,9 +7203,9 @@ rb_stat_W(VALUE obj)
* stat.world_writable? -> integer or nil
*
* 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).
+ * 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"
@@ -7345,8 +7338,7 @@ rb_stat_f(VALUE obj)
* call-seq:
* stat.zero? -> true or false
*
- * Returns true if stat is a zero-length file;
- * false otherwise.
+ * Returns +true+ if stat is a zero-length file; +false+ otherwise.
*
* File.stat("testfile").zero? #=> false
*
@@ -7384,9 +7376,9 @@ rb_stat_s(VALUE obj)
* call-seq:
* stat.setuid? -> true or false
*
- * Returns true if stat has the set-user-id
- * permission bit set, false if it doesn't or if the
- * operating system doesn't support this feature.
+ * Returns +true+ if stat has the set-user-id permission bit set,
+ * +false+ if it doesn't or if the operating system doesn't support this
+ * feature.
*
* File.stat("/bin/su").setuid? #=> true
*/
@@ -7404,9 +7396,9 @@ rb_stat_suid(VALUE obj)
* call-seq:
* stat.setgid? -> true or false
*
- * Returns true if stat has the set-group-id
- * permission bit set, false if it doesn't or if the
- * operating system doesn't support this feature.
+ * Returns +true+ if stat has the set-group-id permission bit set,
+ * +false+ if it doesn't or if the operating system doesn't support this
+ * feature.
*
* File.stat("/usr/sbin/lpc").setgid? #=> true
*
@@ -7425,9 +7417,8 @@ rb_stat_sgid(VALUE obj)
* call-seq:
* stat.sticky? -> true or false
*
- * Returns true if stat has its sticky bit set,
- * false if it doesn't or if the operating system doesn't
- * support this feature.
+ * Returns +true+ if stat has its sticky bit set, +false+ if it
+ * doesn't or if the operating system doesn't support this feature.
*
* File.stat("testfile").sticky? #=> false
*
@@ -8417,11 +8408,11 @@ const char ruby_null_device[] =
* Higher-order bits in permissions may indicate the type of file
* (plain, directory, pipe, socket, etc.) and various other special features.
*
- * On non-Posix operating systems, permissions may include only read-only or read-write,
- * in which case, the remaining permission will resemble typical values.
- * On Windows, for instance, the default permissions are 0644;
- * The only change that can be made is to make the file
- * read-only, which is reported as 0444.
+ * On non-Posix operating systems, permissions may include only read-only or
+ * read-write, in which case, the remaining permission will resemble typical
+ * values. On Windows, for instance, the default permissions are +0644+; The
+ * only change that can be made is to make the file read-only, which is
+ * reported as +0444+.
*
* For a method that actually creates a file in the underlying platform
* (as opposed to merely creating a \File object),
diff --git a/io.c b/io.c
index 6ae91a6b37f07a..f8b93c65b5e8ba 100644
--- a/io.c
+++ b/io.c
@@ -3055,16 +3055,21 @@ rb_io_pid(VALUE io)
}
/*
+ * :markup: markdown
+ *
* call-seq:
* path -> string or nil
*
- * Returns the path associated with the IO, or +nil+ if there is no path
- * associated with the IO. It is not guaranteed that the path exists on
- * the filesystem.
+ * Returns the string path associated with `self`,
+ * or `nil` if there is no associated path:
*
- * $stdin.path # => ""
+ * ```ruby
+ * path = 'doc/maintainers.md'
+ * fd = File.open(path).fileno # => 6
+ * IO.new(fd, path: path).path # => "doc/maintainers.md"
+ * IO.new(fd).path # => nil
+ * ```
*
- * File.open("testfile") {|f| f.path} # => "testfile"
*/
VALUE
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index d529788edd1722..e9fd6508920d29 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -2633,6 +2633,17 @@ def test_permutation
assert_equal(b, @cls[0, 1, 2, 3, 4][1, 4].permutation.to_a, bug3708)
end
+ def test_permutation_array_modified
+ ary = @cls[*(1..1000)]
+ cls = @cls
+ obj = Object.new
+ obj.define_singleton_method(:to_int) do
+ ary.replace(cls[1, 2])
+ 2
+ end
+ assert_equal(@cls[[1, 2], [2, 1]], ary.permutation(obj).to_a)
+ end
+
def test_permutation_stack_error
bug9932 = '[ruby-core:63103] [Bug #9932]'
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 30)