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
  • ----- 2025 -----
  • 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

March 2025

  • 1 participants
  • 162 discussions
[ruby-core:121429] [Ruby Bug#21196] Ruby 3.4 ignores visibility when passing arguments using `...`
by toy (Ivan Kuchin) 21 Mar '25

21 Mar '25
Issue #21196 has been reported by toy (Ivan Kuchin). ---------------------------------------- Bug #21196: Ruby 3.4 ignores visibility when passing arguments using `...` https://bugs.ruby-lang.org/issues/21196 * Author: toy (Ivan Kuchin) * Status: Open * ruby -v: ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- If method is passing arguments using `...`, then receiver visibility gets ignored if once called without receiver: ```ruby class A private def foo = :foo def bar = :bar end class B def initialize(o) @o = o end def foo(...) = @o.foo(...) def bar = @o.bar def internal_foo = foo def internal_bar = bar end def try p yield rescue => e p e end ``` If `foo` is called first without receiver through `internal_foo`: ```ruby b = B.new(A.new) try{ b.internal_foo } try{ b.internal_bar } try{ b.foo } try{ b.bar } ``` Visibility of `A#foo` gets ignored: ``` ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux] :foo #<NoMethodError: private method 'bar' called for an instance of A> :foo #<NoMethodError: private method 'bar' called for an instance of A> ``` ``` ruby 3.3.7 (2025-01-15 revision be31f993d7) [x86_64-linux] #<NoMethodError: private method `foo' called for an instance of A> #<NoMethodError: private method `bar' called for an instance of A> #<NoMethodError: private method `foo' called for an instance of A> #<NoMethodError: private method `bar' called for an instance of A> ``` If `internal_foo` is not called before `foo`: ```ruby b = B.new(A.new) try{ b.foo } try{ b.bar } ``` Visibility of `A#foo` gets checked: ``` ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux] #<NoMethodError: private method 'foo' called for an instance of A> #<NoMethodError: private method 'bar' called for an instance of A> ``` ``` ruby 3.3.7 (2025-01-15 revision be31f993d7) [x86_64-linux] #<NoMethodError: private method `foo' called for an instance of A> #<NoMethodError: private method `bar' called for an instance of A> ``` -- https://bugs.ruby-lang.org/
2 2
0 0
[ruby-core:121421] [Ruby Feature#21194] How to manage application-level information in Ruby application
by mame (Yusuke Endoh) 21 Mar '25

21 Mar '25
Issue #21194 has been reported by mame (Yusuke Endoh). ---------------------------------------- Feature #21194: How to manage application-level information in Ruby application https://bugs.ruby-lang.org/issues/21194 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- ## Goal I want to manage application-level information (e.g., application configuration) while making it easily accessible from the part classes of the application. Additionally, I want to support multiple instances of the application within a single process. ## Current approach 1: Global variables The simplest way to achieve this is by using global variables. ```ruby class MyApp class Part1 def run using $config[:part1]... end end class Part2 def run using $config[:part2]... end end def initialize(config) $config = config @part1 = Part1.new @part2 = Part2.new end def run @part1.run @part2.run end end app1 = MyApp.new({ part1: "aaa", part2: "bbb" }) # app2 = MyApp.new({ part1: "AAA", part2: "BBB" }) # Cannot create this app1.run ``` This code is simple and clear, but it does not allow creating multiple `MyApp` instances with different configurations. To achieve that, we would need to create separate process using `fork` or `spawn`. This limitation remains even if we replace global variables with constants (`MyApp::Config`) or class methods (`MyApp.config`). ## Current approach 2: Passing configuration via `initialize` A textbook and well-structured approach is to explicitly pass configuration through `initialize`. ```ruby class MyApp class Part1 def initialize(config) @config = config end def run using @config[:part1]... end end class Part2 def initialize(config) @config = config end def run using @config[:part2]... end end def initialize(config) @part1 = Part1.new(config) @part2 = Part2.new(config) end def run @part1.run @part2.run end end app1 = MyApp.new({ part1: ..., part2: ... }) app2 = MyApp.new({ part1: ..., part2: ... }) app1.run app2.run ``` This approach allows creating multiple MyApp instances with different configurations in a single Ruby process. However, it has two major drawbacks: * `config` must be passed explicitly in every `initialize` and `new` call, making the code verbose. * Both `Part1` and `Part2` instances hold their own `@config` variables, which is redundant -- especially when creating a large number of small instances (e.g., tree nodes). ## Current approach 3: Thread-local storage Storing configuration in `Thread[:config]` allows multiple application instances without explicit parameter passing. ```ruby class MyApp class Part1 def run using Thread[:config][:part1]... end end class Part2 def run using Thread[:config][:part2]... end end def initialize(config) @config = config @part1 = Part1.new @part2 = Part2.new end def run Thread[:config] = config @part1.run @part2.run end end app1 = MyApp.new({ part1: ..., part2: ... }) app2 = MyApp.new({ part1: ..., part2: ... }) app1.run app2.run ``` This approach is mostly effective but has an issue: * `Thread[:config] = @config` must be set at the beginning of `MyApp#run`. While this is manageable if there is only one public API, it becomes error-prone when multiple APIs exist. Note that using `Fiber#[]` instead of `Thread#[]` has the same issue. ## Proposal Ideally, we want to support multiple application instances while keeping the simplicity of the global variable approach. To achieve this, I propose introducing a new type variable, such as `$@config`: * `$@config` belongs to an instance * When accessing `$@config`, it is looked up not only in `self` but also by traversing the call stack to find the nearest `self` instance that has `$@config`. With this, the code could be written as follows: ```ruby class MyApp class Part1 def run $@config[:part1] # accesses MyApp's $@config end end class Part2 def run $@config[:part2] end end def initialize(config) $@config = config @part1 = Part1.new @part2 = Part2.new end def run @part1.run @part2.run end end app1 = MyApp.new({ part1: ..., part2: ... }) app2 = MyApp.new({ part1: ..., part2: ... }) app1.run app2.run ``` This behaves similarly to dynamically scoped variables but differs in that it is resolved through the `self` instances. (`Thread.new` is a bit problematic: if you use `Thread.new` in a method of `MyApp::Part1`, you wouldn't have access to `$@config` in it. It might be nice to take over all `$@x` variables.) ## Feedback wanted Whenever I write a large Ruby application, I encounter this problem. However, TBH, I am not entirely confident that my proposed solution is the best one. Do you ever encounter this problem? How do you deal with the problem when you do? Is there a better workaround? -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:121420] [Ruby Bug#18878] parse.y: Foo::Bar {} is inconsistently rejected
by qnighy (Masaki Hara) 21 Mar '25

21 Mar '25
Issue #18878 has been updated by qnighy (Masaki Hara). Now `Foo::Bar {}` parses in parse.y too, but `Foo::Bar {} + 1` still doesn't parse unlike in Prism. ---------------------------------------- Bug #18878: parse.y: Foo::Bar {} is inconsistently rejected https://bugs.ruby-lang.org/issues/18878#change-112403 * Author: qnighy (Masaki Hara) * Status: Open * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The following source doesn't parse: ```ruby Foo::Bar {} ``` despite the following: ```ruby bar # local variable or method call Bar # constant bar() # method call Bar() # method call bar {} # method call Bar {} # method call bar() {} # method call Bar() {} # method call Foo::bar # method call Foo::Bar # constant Foo::bar() # method call Foo::Bar() # method call Foo::bar {} # method call # Foo::Bar {} # SyntaxError Foo::bar() {} # method call Foo::Bar() {} # method call ``` Especially considering `Bar {}`, this looks like a missing implementation rather than an intentional behavior. -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:120128] [Ruby master Bug#20934] `UnboundMethod#bind_call` may cause "double free or corruption" with Ractor
by wanabe (_ wanabe) 20 Mar '25

20 Mar '25
Issue #20934 has been reported by wanabe (_ wanabe). ---------------------------------------- Bug #20934: `UnboundMethod#bind_call` may cause "double free or corruption" with Ractor https://bugs.ruby-lang.org/issues/20934 * Author: wanabe (_ wanabe) * Status: Open * ruby -v: ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When I call `UnboundMethod#bind_call` on both main Ractor and child Ractor, probable errors can be encountered. Here is an issue reproduce script `ractor_issue.rb`. ``` def foo 10000.times do Object.instance_method(:object_id).bind_call(self) end end Ractor.new { foo } foo ``` And there are some examples of execution results. ``` $ ./miniruby -v ractor_issue.rb ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] ractor_issue.rb:7: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. double free or corruption (fasttop) Aborted (core dumped) ``` ``` $ ./miniruby -v ractor_issue.rb ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] ractor_issue.rb:7: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007fc6c16bfb18 run> terminated with exception (report_on_exception is true): ractor_issue.rb:3:in 'UnboundMethod#bind_call': undefined method 'object_id' for main (NoMethodError) from ractor_issue.rb:3:in 'block in Object#foo' from <internal:numeric>:257:in 'Integer#times' from ractor_issue.rb:2:in 'Object#foo' from ractor_issue.rb:8:in '<main>' ``` Please try running it several times, as there is a probability of successful completion. -- https://bugs.ruby-lang.org/
4 4
0 0
[ruby-core:121205] [Ruby master Feature#21163] Inconsistencies in Kernel.Float compared to other number parsing methods
by herwin (Herwin W) 19 Mar '25

19 Mar '25
Issue #21163 has been reported by herwin (Herwin W). ---------------------------------------- Feature #21163: Inconsistencies in Kernel.Float compared to other number parsing methods https://bugs.ruby-lang.org/issues/21163 * Author: herwin (Herwin W) * Status: Open ---------------------------------------- Not sure if I consider the following points to be bugs, but they sure did surprise me: Item 1: Hexadecimal is the only prefix accepted If you use the "0x" prefix, your value is parsed as hexadecimal float: ```ruby Float("0x10") # => 16.0 Float("0x0.8") # => 0.5 # Since Ruby 3.4 ``` This is the only accepted prefix, "010" is not parsed as octal, but as decimal 10. "0b10" and "0o10" are parse errors. If "0x" works, I would expect these to work too. Item 2: Inconsistency with String#to_f String#to_f does not parse hexadecimal strings, "0x10".to_f simply returns 0.0. Generally, the methods in Kernel are stricter than the methods on String, so valid input for the Kernel methods yields the same result in the String methods, I think this is the only exception Item 3: Inconsistency with Kernel#Integer ```ruby Integer("0x1_0a") # => 0x10a Float("0x1_0") # => 16.0 # This underscore is accepted Float("0x1_0a") # => ArgumentError ``` Kernel.Float does accept underscores in hexadecimal strings, but only if all values are digits. As soon as there is a `[a-fA-F]` in the input, it is an ArgumentError -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:121239] [Ruby master Bug#21170] Corrupted Hash (bad VALUE and missing entry) when -1 returned from .hash
by jhawthorn (John Hawthorn) 19 Mar '25

19 Mar '25
Issue #21170 has been reported by jhawthorn (John Hawthorn). ---------------------------------------- Bug #21170: Corrupted Hash (bad VALUE and missing entry) when -1 returned from .hash https://bugs.ruby-lang.org/issues/21170 * Author: jhawthorn (John Hawthorn) * Status: Open * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ``` ruby class MyObj attr_reader :hash def initialize(val) = @hash = val end values = 0.downto(-16).to_a hash = {} values.each do |val| hash[MyObj.new(val)] = val end p hash.values # => [0, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, false, -16] ``` --- st_table reserves -1 as a special hash value to indicate that an entry has been deleted. So that that's a valid value to be returned from the hash function, do_hash replaces -1 with 0 so that it is not mistaken for the sentinel. Previously, when upgrading an AR table to an ST table, rb_st_add_direct_with_hash was used which did not perform the same conversion, this could lead to a hash in a broken state where one if its entries which was supposed to exist being marked as a tombstone. The hash could then become further corrupted when the ST table required resizing as the falsely tombstoned entry would be skipped but it would be counted in num entries, leading to an uninitialized entry at index 15. https://github.com/ruby/ruby/pull/12852 -- https://bugs.ruby-lang.org/
5 5
0 0
[ruby-core:121247] [Ruby master Bug#21173] RUBY_FREE_AT_EXIT does not work when error in -r
by peterzhu2118 (Peter Zhu) 19 Mar '25

19 Mar '25
Issue #21173 has been reported by peterzhu2118 (Peter Zhu). ---------------------------------------- Bug #21173: RUBY_FREE_AT_EXIT does not work when error in -r https://bugs.ruby-lang.org/issues/21173 * Author: peterzhu2118 (Peter Zhu) * Status: Open * Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED ---------------------------------------- PR: https://github.com/ruby/ruby/pull/12859 When loading a file using the command line -r, it is processed before RUBY_FREE_AT_EXIT is checked. So if the loaded file raises an error, it will cause memory to not be freed with RUBY_FREE_AT_EXIT. For example `ruby -rtest.rb -e ""` will report a large amount of memory leaks if `test.rb` raises. -- https://bugs.ruby-lang.org/
2 1
0 0
[ruby-core:121278] [Ruby master Bug#21179] Introduction Happy Eyeballs Version 2 broke `Socket.tcp` from secondary Ractors
by byroot (Jean Boussier) 19 Mar '25

19 Mar '25
Issue #21179 has been reported by byroot (Jean Boussier). ---------------------------------------- Bug #21179: Introduction Happy Eyeballs Version 2 broke `Socket.tcp` from secondary Ractors https://bugs.ruby-lang.org/issues/21179 * Author: byroot (Jean Boussier) * Status: Open * Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED ---------------------------------------- ```ruby require "socket" Ractor.new do Socket.tcp("example.com", 80) end.take ``` ``` socket.rb:1046:in 'Socket::HostnameResolutionStore#get_addrinfo': can not access non-shareable objects in constant Socket::HostnameResolutionStore::PRIORITY_ON_V6 by non-main ractor. (Ractor::IsolationError) from socket.rb:724:in 'block in Socket.tcp_with_fast_fallback' from socket.rb:720:in 'Socket.tcp_with_fast_fallback' ``` Proposed patch: https://github.com/ruby/ruby/pull/12896 -- https://bugs.ruby-lang.org/
2 1
0 0
[ruby-core:121403] [Ruby Bug#21192] Coverage no longer reports coverage information about tracepoint handlers
by deivid 19 Mar '25

19 Mar '25
Issue #21192 has been reported by deivid (David Rodríguez). ---------------------------------------- Bug #21192: Coverage no longer reports coverage information about tracepoint handlers https://bugs.ruby-lang.org/issues/21192 * Author: deivid (David Rodríguez) * Status: Open * ruby -v: 2.6 until now * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- I minimized the issue like this: ### repro.rb ```ruby require "coverage" Coverage.start require_relative "a" puts Coverage.result ``` ### a.rb ```ruby TracePoint.trace(:line) do |tp| puts "TracePoint handler" end puts "Outside" ``` In Ruby 2.5, program's out was: ``` $ docker run --rm -it --mount type=bind,source=$(pwd),target=/foo ruby:2.5 ruby /foo/repro.rb TracePoint handler Outside TracePoint handler {"/foo/a.rb"=>[1, 2, nil, nil, 1]} ``` In Ruby 2.6 or higher: ``` $ docker run --rm -it --mount type=bind,source=$(pwd),target=/foo ruby:3.4 ruby /foo/repro.rb TracePoint handler Outside TracePoint handler {"/foo/a.rb" => [1, 0, nil, nil, 1]} ``` -- https://bugs.ruby-lang.org/
2 3
0 0
[ruby-core:121399] [Ruby Feature#15854] Tracing instance variable assignment
by Eregon (Benoit Daloze) 18 Mar '25

18 Mar '25
Issue #15854 has been updated by Eregon (Benoit Daloze). I think tracing ivar assignments would be prohibitively slow, and so probably not really usable in practice. ---------------------------------------- Feature #15854: Tracing instance variable assignment https://bugs.ruby-lang.org/issues/15854#change-112374 * Author: igaiga (Kuniaki Igarashi) * Status: Assigned * Assignee: ko1 (Koichi Sasada) ---------------------------------------- I suggest a feature "tracing instance variable assignment". It's useful for debugging. Use case: In Rails, we use instance variables in views and controllers. When we got a bug caused by instance variable unintentional values, if we traced instance variable assignment timing, it would be good informations. And in Rails views, there are no source codes of self class. That's built dynamically. Current behavior (Ruby2.6): In Ruby 2.6, only if there is a source code file to assign instance variable, we can trace instance variable assignment by following code (check_instance_variable_assignment.rb). But it's difficult if the assignment codes are defined dynamically. For example, in Rails view. (And in another story, global variables assignment are traced by Kernel#trace_var.) check_instance_variable_assignment.rb ```ruby def trace_start TracePoint.trace(:line) do |tp| target_class_name = "Foo" target_instance_variable_name = "@bar" line = File.open(tp.path, "r"){|f| f.readlines[tp.lineno - 1] } node = RubyVM::AbstractSyntaxTree.parse(line).children.last # check instance variable assignment next unless node.type == :IASGN # check class name target_class = Kernel.const_get(target_class_name) next unless tp.self.is_a?(target_class) # check variable name instance_variable_name = node.children.first next unless instance_variable_name == target_instance_variable_name.to_sym puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.defined_class} #{tp.method_id}" end end class Foo def bar @bar = "text" end end trace_start Foo.new.bar #=> Foo @bar is assigned in check_instance_variable_assignment.rb:25 Foo bar ``` Suggesting feature example: Add new arguments for TracePoint.new method like :line and :call to trace instance variables assignment. - :iasgn (IASGN name from RubyVM::AbstractSyntaxTree::Node) - :casgn (CVASGN (or CASGN?) name from RubyVM::AbstractSyntaxTree::Node. I think class variables tracing is useful too.) And get informations - class name (It might be get by trace_point.self) - variable name ("@foo", "@@foo") A sample code to use the feature: tp_iasgn.rb ```ruby TracePoint.trace(:iasgn) do |tp| target_class_name = "Foo" target_instance_variable_name = "@bar" # check class name target_class = Kernel.const_get(target_class_name) next unless tp.self.is_a?(target_class) # check variable name next unless target_instance_variable_name == tp.variable_name puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}" puts caller # even in dynamic code case, we can get caller informations. end ``` -- https://bugs.ruby-lang.org/
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • ...
  • 17
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.