ml.ruby-lang.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

ruby-core

Thread Start a new thread
Download
Threads by month
  • ----- 2026 -----
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
ruby-core@ml.ruby-lang.org

December 2025

  • 2 participants
  • 215 discussions
[ruby-core:124340] [Ruby Bug#21799] Delegated top-level methods are not visible outside the Ruby Box
by koic (Koichi ITO) 23 Dec '25

23 Dec '25
Issue #21799 has been reported by koic (Koichi ITO). ---------------------------------------- Bug #21799: Delegated top-level methods are not visible outside the Ruby Box https://bugs.ruby-lang.org/issues/21799 * Author: koic (Koichi ITO) * Status: Open * ruby -v: ruby 4.0.0dev (2025-12-21T19:08:00Z master cfb324e9d1) +PRISM [arm64-darwin24] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The following example code based on Ruby Box results in an unexpected error. https://github.com/ruby/ruby/blob/v4.0.0-preview3/doc/language/box.md#top-l… I'm not familiar with Ruby Box, but it seems that either the above documentation example in doc/language/box.md or the Ruby Box implementation is incorrect. ## Steps to reproduce ```console $ cat main.rb box = Ruby::Box.new box.require_relative('foo') p box.Foo.say #=> "foo" p yay # NoMethodError ``` ```console $ cat foo.rb def yay = "foo" class Foo def self.say = yay end p Foo.say #=> "foo" p yay #=> "foo" ``` ## Expected According to the documentation example, `box.Foo.say` in `main.rb` should return the string `"foo"`. ## Actual Contrary to the documentation example, calling `box.Foo.say` in `main.rb` raises a `NoMethodError`. ```console $ RUBY_BOX=1 ruby main.rb ruby: warning: Ruby::Box is experimental, and the behavior may change in the future! See doc/language/box.md for known issues, etc. "foo" "foo" main.rb:4:in '<main>': undefined method 'Foo' for module #<Ruby::Box:3,user,optional> (NoMethodError) p box.Foo.say #=> "foo" ^^^^ ``` ## Additional Information According to the description below, the documentation example might not be appropriate, but it's unclear what visibility delegated top-level methods have. > Currently, top level methods in boxes are not accessible from outside of the box. But there might be a use case to call other box's top level methods. https://github.com/ruby/ruby/blob/v4.0.0-preview3/doc/language/box.md#expos… -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:124343] [Ruby Feature#17001] [Feature] Dir.scan to yield dirent for efficient and composable recursive directory scaning
by byroot (Jean Boussier) 22 Dec '25

22 Dec '25
Issue #17001 has been updated by byroot (Jean Boussier). Status changed from Open to Closed Closing in favor of [Feature #21800] ---------------------------------------- Feature #17001: [Feature] Dir.scan to yield dirent for efficient and composable recursive directory scaning https://bugs.ruby-lang.org/issues/17001#change-115849 * Author: byroot (Jean Boussier) * Status: Closed ---------------------------------------- ### Use case When you need to recusrsively scan a directory, you either have to use `Dir[]` / `Dir.glob`, which is fine for small directories or simple patterns, but can easily take several seconds to complete for large repositories or complex patterns and returns a very large array which tend to trash GC. Or you can use `Dir.each_entry` / `Dir.foreach` recursively, but then you need to `stat` each entry to know wether it's a directory, or even symlink if you want to follow them. This means one syscall per directory, and one per file and directories. This is particularly impactful on OSX where `stat()` is several times slower than on Linux because of various sandboxing features. There's a [typical example of this use case in Bootsnap](https://github.com/Shopify/bootsnap/blob/56c61373000573112ee027da…. ### Proposal [Python introduced `os.scandir` a few years ago](https://www.python.org/dev/peps/pep-0471/) for exactly this purpose. It is functionaly similar to `Dir.foreach` / `Dir.each_child`, except it yields `DirEntry` instances which are a wrapper around the `libc` `dirent` struct. I reduced the Bootsnap code into a [simplified benchmark](https://gist.github.com/casperisfine/2124f349c6564560df4399f2ead…, and using `os.scandir()` Python scan our main repo in a bit over `1s`, which 3 to 4 times faster than Ruby can with `Dir.foreach` (`3-4s`). For comparison sake `Dir['**/*.rb']` also complete in about `1s`. So I beleive that exposing a similar `Dir.scan` method, returning `Dir::Entry` instances, with methods inspired from `File::Stat` such as `directory?` would allow for more performant file system scaning when the query is not easily expressed with a glob pattern. -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:124292] [Ruby Bug#21792] 4.0.0-preview2: Build fails with `--with-ext=` when ENABLE_SHARED=yes: ruby/digest.h not found for rubyspec CAPI extensions
by mdalessio (Mike Dalessio) 20 Dec '25

20 Dec '25
Issue #21792 has been reported by mdalessio (Mike Dalessio). ---------------------------------------- Bug #21792: 4.0.0-preview2: Build fails with `--with-ext=` when ENABLE_SHARED=yes: ruby/digest.h not found for rubyspec CAPI extensions https://bugs.ruby-lang.org/issues/21792 * Author: mdalessio (Mike Dalessio) * Status: Open * Target version: 4.0 ---------------------------------------- When building Ruby with `--enable-shared` and `--with-ext=` (empty, to disable all extensions), the build fails because spec/ruby/optional/capi/ext/digest_spec.c cannot find ruby/digest.h. This affects cross-compilation tooling like `rake-compiler` which uses these configure options to build a minimal Ruby for cross-compiling native gems. ## Reproducing Download and extract ruby-4.0.0-preview2 source code. ``` cd ruby-4.0.0-preview2 ./configure --enable-shared --disable-install-doc --with-ext= make ``` Or alternatively, use rake-compiler: ``` mkdir ~/.rake-compiler rake-compiler cross-ruby VERSION=4.0.0-preview2 HOST=x86_64-linux-gnu ``` Either way, you will see: ``` spec/ruby/optional/capi/ext/digest_spec.c:4:10: fatal error: ruby/digest.h: No such file or directory 4 | #include "ruby/digest.h" | ^~~~~~~~~~~~~~~ compilation terminated. make: *** [defs/gmake.mk:521: spec/ruby/optional/capi/ext/digest_spec.so] Error 1 ``` ## Root Cause I believe the root cause is: 1. defs/gmake.mk:531-532 unconditionally adds rubyspec-capiext to the exts target when ENABLE_SHARED=yes: ``` ifeq ($(ENABLE_SHARED),yes) exts: rubyspec-capiext endif ``` 2. rubyspec-capiext builds all *.c files in spec/ruby/optional/capi/ext/, including digest_spec.c 3. digest_spec.c (line 4) includes ruby/digest.h 4. ruby/digest.h is only installed when the digest extension is built. From ext/digest/extconf.rb:7-9: ``` $INSTALLFILES = { "digest.h" => "$(HDRDIR)" } if $extmk ``` 5. With --with-ext= (empty), the digest extension is not built, so digest.h is never copied to .ext/include/ruby/ 6. The build fails because digest_spec.c requires a header that was never installed Note that before 269ad29d, no rubyspec CAPI extension required extension-specific headers, so this configuration worked. -- https://bugs.ruby-lang.org/
3 7
0 0
[ruby-core:124051] [Ruby Feature#21767] Consider procs which `self` is Ractor-shareable as Ractor shareable
by osyoyu (Daisuke Aritomo) 20 Dec '25

20 Dec '25
Issue #21767 has been reported by osyoyu (Daisuke Aritomo). ---------------------------------------- Feature #21767: Consider procs which `self` is Ractor-shareable as Ractor shareable https://bugs.ruby-lang.org/issues/21767 * Author: osyoyu (Daisuke Aritomo) * Status: Open ---------------------------------------- I would like to allow procs which `self` is Ractor-shareable to be automatically eligible as shareable, without an explicit `Ractor.make_shareable` call. ```ruby class C PROC = proc { p ARRAY }.freeze end Ractor.new { C::PROC.call }.value # Allow this, since `C` is shareable ``` Proposal is: Consider procs/lambdas which meet the following condition as Ractor-shareable. - The proc is frozen. - The proc's `self` is shareable. This proposal is has taken inspiration from #21033 . ## Usecase The main usecase in mind is procs/lambdas in class-level constants. Some libraries store procs in constants as a convenient place for library-wide logic. Those procs usually do not access unshareable state, thus conceptually safe to be shared across Ractors. However, the current limitation completely blocks this. Examples may be found in ruby/ruby, and I have submitted a pull request to migrate one to `Ractor.shareable_proc`. ```ruby class Pathname SAME_PATHS = if File::FNM_SYSCASE.nonzero? # Avoid #zero? here because #casecmp can return nil. proc {|a, b| a.casecmp(b) == 0} else proc {|a, b| a == b} end end ``` https://github.com/search?q=repo%3Aruby%2Fruby%20%2F(%3F-i)%5BA-Z%5D%20%3D%… More examples can be found in public code. https://github.com/search?q=language%3Aruby+%2F%28%3F-i%29%5BA-Z%5D+%3D+%28… It can be observed that a good portion of these do not access unshareable state. Appending `.freeze` would be much more acceptable than redefining using `Ractor.shareable_proc`, which is a Ruby 4.0-only feature. ## Discussion: Change of behavior when illegal access occurs in proc Consider this code. The proc accesses non-frozen `C::ARRAY`, which is against the rules of Ractors regardless of this patch. ```ruby class C ARRAY = [] PROC = proc { p ARRAY } end # Still illegal since C::ARRAY is not shareable Ractor.new { C::PROC.call }.value ``` This code used to raise on `C::PROC.call` (`can not access non-shareable objects in constant C::PROC by non-main Ractor.`). When this patch is applied, it will raise on `p ARRAY` (`can not access non-shareable objects in constant C::ARRAY by non-main ractor.`). This could be debatable change. If this is not acceptable, I'd like to revisit #21033 . -- https://bugs.ruby-lang.org/
3 4
0 0
[ruby-core:124307] [Ruby Bug#21794] O_CLOEXEC is not available on Solaris 10
by ngoto (Naohisa Goto) 19 Dec '25

19 Dec '25
Issue #21794 has been reported by ngoto (Naohisa Goto). ---------------------------------------- Bug #21794: O_CLOEXEC is not available on Solaris 10 https://bugs.ruby-lang.org/issues/21794 * Author: ngoto (Naohisa Goto) * Status: Open * ruby -v: ruby 4.0.0dev (2025-12-18T07:47:43Z master 9f266ae674) +PRISM [sparc64-solaris2.10] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Because O_CLOEXEC is not available on Solaris 10, an error occurs when compiling box.c: "'O_CLOEXEC' undeclared (first use in this function)" ``` gcc -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE -I. -I.ext/include/sparc64-solaris2.10 -I.ext/include -I../ruby.devel.ORIG/include -I../ruby.devel.ORIG -I../ruby.devel.ORIG/prism -I../ruby.devel.ORIG/enc/unicode/17.0.0 -Dmodular_gc_dir="" -D_XOPEN_SOURCE=600 -I/usr/local/64/lib/libffi-3.0.10/include -I/usr/local/64/include -o box.o -c ../ruby.devel.ORIG/box.c ../ruby.devel.ORIG/box.c: In function 'copy_ext_file': ../ruby.devel.ORIG/box.c:634:63: error: 'O_CLOEXEC' undeclared (first use in this function); did you mean 'FD_CLOEXEC'? const int dst_fd = open(dst_path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|bin, S_IRWXU); ^~~~~~~~~ FD_CLOEXEC ../ruby.devel.ORIG/box.c:634:63: note: each undeclared identifier is reported only once for each function it appears in ../ruby.devel.ORIG/box.c: At top level: cc1: warning: unrecognized command line option '-Wno-self-assign' cc1: warning: unrecognized command line option '-Wno-parentheses-equality' cc1: warning: unrecognized command line option '-Wno-constant-logical-operand' cc1: warning: unrecognized command line option '-Wno-cast-function-type' make: *** [box.o] Error 1 ``` The following quick patch resolved the error. ``` diff --git a/box.c b/box.c index 14f6acdd82..120bef3d3d 100644 --- a/box.c +++ b/box.c @@ -631,7 +631,25 @@ copy_ext_file(const char *src_path, const char *dst_path) return COPY_ERROR_SRC_STAT; } +#ifdef O_CLOEXEC const int dst_fd = open(dst_path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|bin, S_IRWXU); +#else + int tmp_dst_fd = open(dst_path, O_WRONLY|O_CREAT|O_EXCL|bin, S_IRWXU); + do { + int dst_fd_flags; + if (tmp_dst_fd < 0) break; + dst_fd_flags = fcntl(tmp_dst_fd, F_GETFD, 0); + if (dst_fd_flags > 0) { + dst_fd_flags |= FD_CLOEXEC; + if (fcntl(tmp_dst_fd, F_SETFD, dst_fd_flags) == 0) break; + /* error */ + close(tmp_dst_fd); + tmp_dst_fd = -1; + break; + } + } while(0); + const int dst_fd = tmp_dst_fd; +#endif if (dst_fd < 0) { close(src_fd); return COPY_ERROR_DST_OPEN; ``` Note that Solaris 11 has O_CLOEXEC. If someone argues that we no longer need to support older operating systems that lack O_CLOEXEC, I find it very difficult to counter that argument. -- https://bugs.ruby-lang.org/
2 2
0 0
[ruby-core:123845] [Ruby Bug#21696] Performance degradation for long running processes in Ruby 4.0.0-preview2
by easydwh (Ivo Herweijer) 19 Dec '25

19 Dec '25
Issue #21696 has been reported by easydwh (Ivo Herweijer). ---------------------------------------- Bug #21696: Performance degradation for long running processes in Ruby 4.0.0-preview2 https://bugs.ruby-lang.org/issues/21696 * Author: easydwh (Ivo Herweijer) * Status: Open * ruby -v: ruby 4.0.0preview2 (2025-11-17 master 4fa6e9938c) +PRISM [x86_64-linux] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- When running my RubyMeasureResponsetime tool (https://github.com/easydatawarehousing/ruby_measure_responsetime) on Ruby 4.0.0-preview2, a slow but steady performance degradation is measurable. Both the Rails and the Roda based test applications show this. And both with and without yjit. The Rails application when using yjit also seems to have increasing memory usage over time. Running the same tests on Ruby 3.4.7 shows stable performance and memory usage. I have included some plots showing this behavior. ---Files-------------------------------- rails_devise_2_ruby-4.0.0.jpg (965 KB) rodauth_2_ruby-4.0.0 YJIT.jpg (973 KB) rodauth_2_ruby-4.0.0.jpg (1.02 MB) rails_devise_2_ruby-4.0.0 YJIT.jpg (917 KB) rails_devise_0_memory.png (31.2 KB) -- https://bugs.ruby-lang.org/
3 5
0 0
[ruby-core:124289] [Ruby Feature#21791] Implement Set#compact/Set#compact!, these should return Set instead of Array
by herwin (Herwin W) 19 Dec '25

19 Dec '25
Issue #21791 has been reported by herwin (Herwin W). ---------------------------------------- Feature #21791: Implement Set#compact/Set#compact!, these should return Set instead of Array https://bugs.ruby-lang.org/issues/21791 * Author: herwin (Herwin W) * Status: Open ---------------------------------------- I recently had to remove a nil value from a Set, and ended up with an Array: ``` irb(main):001> Set[1, 2, nil, 3].compact => [1, 2, 3] irb(main):002> Set[1, 2, nil, 3].compact.class => Array ``` Since there is no dedicated `Set#compact`, this is done via `Enumerable#compact` and this results in an Array. To preserve the Set, the following works: ```ruby set - [nil] # compact set.delete_if(&:nil?) # compact! set.compact.to_set # compact, but slow ``` Both are rather ugly. This patch implements `Set#compact` and `Set#compact!` in a way that preserves the class. There are probably more methods that could have their own implementation, for example `Set#select`/`Set#reject` now returns arrays too (but `Set#select!` and `Set#reject!` work as expected. Pull request: https://github.com/ruby/ruby/pull/15614 -- https://bugs.ruby-lang.org/
2 2
0 0
[ruby-core:124305] [Ruby Bug#21793] function name conflict of "mutex_trylock" on Solaris
by ngoto (Naohisa Goto) 18 Dec '25

18 Dec '25
Issue #21793 has been reported by ngoto (Naohisa Goto). ---------------------------------------- Bug #21793: function name conflict of "mutex_trylock" on Solaris https://bugs.ruby-lang.org/issues/21793 * Author: ngoto (Naohisa Goto) * Status: Open * ruby -v: ruby 4.0.0dev (2025-12-18T07:47:43Z master 9f266ae674) +PRISM [sparc64-solaris2.10] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- On Solaris, with GCC 7.5.0, failed to compile thread.c with "error: conflicting types for 'mutex_trylock'". On Solaris, the function name mutex_trylock(3C) is already used by the OS. https://docs.oracle.com/cd/E88353_01/html/E37843/mutex-trylock-3c.html It is a part of historical pre-POSIX mutex implementation, but it seems that it may still be internally used by the OS. Could you please change the name of "mutex_trylock" in thread_sync.c:238 to something else? The compile error message is below: ``` gcc -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE -I. -I.ext/include/sparc64-solaris2.10 -I.ext/include -I../ruby.devel/include -I../ruby.devel -I../ruby.devel/prism -I../ruby.devel/enc/unicode/17.0.0 -Dmodular_gc_dir="" -D_XOPEN_SOURCE=600 -I/usr/local/64/lib/libffi-3.0.10/include -I/usr/local/64/include -o thread.o -c ../ruby.devel/thread.c In file included from ../ruby.devel/thread.c:293:0: ../ruby.devel/thread_sync.c:238:1: error: conflicting types for 'mutex_trylock' mutex_trylock(rb_mutex_t *mutex, rb_thread_t *th, rb_serial_t ec_serial) ^~~~~~~~~~~~~ In file included from /usr/include/thread.h:24:0, from ../ruby.devel/thread_pthread.c:21, from ../ruby.devel/thread.c:278: /usr/include/synch.h:94:5: note: previous declaration of 'mutex_trylock' was here int mutex_trylock(mutex_t *); ^~~~~~~~~~~~~ ../ruby.devel/thread.c: In function 'rb_gc_set_stack_end': ../ruby.devel/thread.c:4809:44: warning: unknown option after '#pragma GCC diagnostic' kind [-Wpragmas] COMPILER_WARNING_IGNORED(-Wdangling-pointer); ^ ../ruby.devel/thread.c: At top level: cc1: warning: unrecognized command line option '-Wno-self-assign' cc1: warning: unrecognized command line option '-Wno-parentheses-equality' cc1: warning: unrecognized command line option '-Wno-constant-logical-operand' cc1: warning: unrecognized command line option '-Wno-cast-function-type' make: *** [thread.o] Error 1 ``` The mutex_trylock function also exists in the Linux kernel, but is only available when the Linux kernel headers are included, so name conflicts may only occur in very specific, rare cases on Linux. https://manpages.debian.org/testing/linux-manual-4.8/mutex_trylock.9.en.html -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:118957] [Ruby master Bug#20699] On Windows, the `__dir__` keyword is garbled in paths containing Japanese characters, and `require_relative` fails as well
by flatland001 (Hayato Arai) 18 Dec '25

18 Dec '25
Issue #20699 has been reported by flatland001 (Hayato Arai). ---------------------------------------- Bug #20699: On Windows, the `__dir__` keyword is garbled in paths containing Japanese characters, and `require_relative` fails as well https://bugs.ruby-lang.org/issues/20699 * Author: flatland001 (Hayato Arai) * Status: Open * ruby -v: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x64-mingw-ucrt] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- In paths containing Japanese characters, such as: C:\テスト_test\test.rb Code: ``` ruby # this code -> C:\テスト_test\test.rb # external file -> C:\テスト_test\lib\foo.rb p __dir__ p __dir__.encoding p File.dirname(File.expand_path(__FILE__)) p File.dirname(File.expand_path(__FILE__)).encoding print "__dir__ == File.dirname(File.expand_path(__FILE__)): " p __dir__ == File.dirname(File.expand_path(__FILE__)) begin require_relative "lib/foo" puts "foo.rb loaded" rescue LoadError puts "LoadError: #{$!}" end ``` Results: ``` "C:/?e?X?g_test" #<Encoding:Windows-31J> "C:/\x{8365}\x{8358}\x{8367}_test" #<Encoding:Windows-31J> __dir__ == File.dirname(File.expand_path(__FILE__)): false LoadError: cannot load such file -- C:/?e?X?g_test/lib/foo ``` However, in ruby 3.2.5 (2024-07-26 revision 31d0f1a2e7) [x64-mingw-ucrt], the same code produces the following expected results: ``` "C:/\x{8365}\x{8358}\x{8367}_test" #<Encoding:Windows-31J> "C:/\x{8365}\x{8358}\x{8367}_test" #<Encoding:Windows-31J> __dir__ == File.dirname(File.expand_path(__FILE__)): true foo.rb loaded ``` Is this behavior expected, or could this be a bug in the Ruby interpreter on Windows? If this is my misunderstanding or a known issue, I apologize. Thank you for your consideration. Environment Information: - OS: Windows 11 Pro 23H2 (OS build 22631.4037) - Installed via: RubyInstaller - Shell: Command Prompt - File System: NTFS - System Locale: Japanese (Japan), Language: Japanese -- https://bugs.ruby-lang.org/
3 3
0 0
[ruby-core:120743] [Ruby master Bug#21049] Reconsider handling of the numbered parameters and "it" parameter in `Binding#local_variables`
by mame (Yusuke Endoh) 18 Dec '25

18 Dec '25
Issue #21049 has been reported by mame (Yusuke Endoh). ---------------------------------------- Bug #21049: Reconsider handling of the numbered parameters and "it" parameter in `Binding#local_variables` https://bugs.ruby-lang.org/issues/21049 * Author: mame (Yusuke Endoh) * Status: Open * Assignee: matz (Yukihiro Matsumoto) * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Currently, `Binding#local_variable*` APIs wrongly handles the numbered parameters. ```ruby # Binding#local_variables includes numbered parameters that should not be visible "foo".tap do _1 "bar".tap do p binding.local_variables #=> expected: [], actual: [:_1] end end # Binding#local_variable_get can read numbered parameters that should not be readable "foo".tap do _1 "bar".tap do p binding.local_variable_get(:_1) #=> expected: NameError, actual: "foo" end end # Binding#local_variable_set can update numbered parameter "foo".tap do p _1 #=> "foo" binding.local_variable_set(:_1, "bar") # expected: NameError, actual: updates _1 p _1 #=> "bar" end ``` My proposal is to stop handling numbered parameters and "it" parameter in `Binding#local_variable*` APIs. ```ruby "foo".tap do _1 binding.local_variables #=> proposed: [] binding.local_variable_get(:_1) #=> proposed: NameError end ``` Here is a proof-of-concept patch. https://github.com/ruby/ruby/pull/12601 It would be theoretically possible to fix `Binding#local_variable*` APIs to handle numbered parameters while maintaining compatibility as much as possible. However, I think the implicit “it” parameter introduced in Ruby 3.4 poses a spec-level problem. This is because there is no way to distinguish between the implicit “it” parameter and a true local variable named "it". Also, I don't think numbered parameters are local variables, so I feel uncomfortable handling them by `Binding#local_variable*` APIs. If it is absolutely necessary to access numbered parameters or "it" parameter via binding, it would be good to introduce dedicated APIs for the purpose, as: * Binding#numbered_parameters #=> [:_1, :_2, :_3, ...] * Binding#numbered_parameter_get(:_1) #=> obj * Binding#numbered_parameter_defined?(:_1) #=> true or false * Binding#it_get #=> obj * Binding#it_defined? #=> true or false Personally, however, I do not see the need for these APIs currently. I implemented them as proof-of-concept in PR, but I am okay that they are not introduced. -- https://bugs.ruby-lang.org/
3 5
0 0
  • ← Newer
  • 1
  • ...
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • ...
  • 22
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.