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)