From: marcandre-ruby-core@... Date: 2020-11-20T22:06:34+00:00 Subject: [ruby-core:100994] [Ruby master Bug#9580] Refinements regression in IRB Issue #9580 has been updated by marcandre (Marc-Andre Lafortune). I ran into this today. We really should change the default to something that works for refinements. I note that: ```sh irb --single-irb # => works (shared context for nested sessions) irb --context 0 # => works irb --context 1 # => works irb --context 2 # => works irb --context 3 # (default) => does not work ``` I get the same stacktraces in all modes in Ruby 2.7. I am proposing a new default context in https://github.com/ruby/irb/pull/138 but any other context mode seems better than the current one. ---------------------------------------- Bug #9580: Refinements regression in IRB https://bugs.ruby-lang.org/issues/9580#change-88660 * Author: davidbalbert (David Albert) * Status: Open * Priority: Normal * ruby -v: 2.2.0dev ---------------------------------------- The problem: Top level refinements do not work in IRB. They worked in 2.0.0-p451, but don't work in 2.1.0, 2.1.1, or today's trunk. Details: Here some code in a file: #refine.rb module A refine String do def asdf :asdf end end end using A p "foo".asdf In all versions, of Ruby between 2.0.0-p451 and 2.2.0dev, running this file, prints `:asdf`. This is the expected behavior. Ruby 2.0.0 also prints the "Refinements are experimental" warning, as expected: # Ruby 2.0.0-p451 $ ruby refine.rb refine.rb:2: warning: Refinements are experimental, and the behavior may change in future versions of Ruby! :asdf # Ruby 2.1.0, 2.1.1, and 2.2.0dev $ ruby refine.rb :asdf In Ruby 2.0.0-p451, the same code also works in IRB, also as expected: irb(main):001:0> "#{RUBY_VERSION}-#{RUBY_PATCHLEVEL}" => "2.0.0-451" irb(main):002:0> module A irb(main):003:1> refine String do irb(main):004:2* def asdf irb(main):005:3> :asdf irb(main):006:3> end irb(main):007:2> end irb(main):008:1> end (irb):3: warning: Refinements are experimental, and the behavior may change in future versions of Ruby! => # irb(main):009:0> using A => main irb(main):010:0> "foo".asdf => :asdf However, in all newer versions of Ruby (2.1.0, 2.1.1, and 2.2.0dev), this code raises a `NoMethodError` in IRB: irb(main):001:0> RUBY_VERSION => "2.1.0" irb(main):002:0> module A irb(main):003:1> refine String do irb(main):004:2* def asdf irb(main):005:3> :asdf irb(main):006:3> end irb(main):007:2> end irb(main):008:1> end => # irb(main):009:0> using A => main irb(main):010:0> "foo".asdf NoMethodError: undefined method `asdf' for "foo":String from (irb):10 from out/bin/irb:11:in `
' irb(main):001:0> RUBY_VERSION => "2.1.1" irb(main):002:0> module A irb(main):003:1> refine String do irb(main):004:2* def asdf irb(main):005:3> :asdf irb(main):006:3> end irb(main):007:2> end irb(main):008:1> end => # irb(main):009:0> using A => main irb(main):010:0> "foo".asdf NoMethodError: undefined method `asdf' for "foo":String from (irb):10 from bin/irb:11:in `
' irb(main):001:0> RUBY_VERSION => "2.2.0" irb(main):002:0> module A irb(main):003:1> refine String do irb(main):004:2* def asdf irb(main):005:3> :asdf irb(main):006:3> end irb(main):007:2> end irb(main):008:1> end => # irb(main):009:0> using A => main irb(main):010:0> "foo".asdf NoMethodError: undefined method `asdf' for "foo":String from (irb):10 from bin/irb:11:in `
' This seems like a bug because the code behaves differently in IRB than how it behaves in the file. If it's the intended behavior, it's frustrating because it makes it harder to prototype code that uses refinements in the REPL. This issue is not specific to IRB. I get the same behavior in Pry (works in 2.0.0, doesn't work in newer Ruby versions). This makes me think the issue is not inside the IRB source, but rather has something to do with `using`'s behavior in the `Binding` objects that IRB and Pry are probably using. I haven't looked at the Pry or IRB source in quite a long time, so this paragraph is mostly speculation. Please let me know if there's any more info I can provide to make this easier to fix -- https://bugs.ruby-lang.org/ Unsubscribe: