Project

General

Profile

Actions

Bug #9580

closed

Refinements regression in IRB

Added by davidbalbert (David Albert) almost 8 years ago. Updated 9 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
2.2.0dev
Backport:
[ruby-core:61150]

Description

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!
=> #<refinement:String@A>
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
=> #<refinement:String@A>
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 `<main>'


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
=> #<refinement:String@A>
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 `<main>'


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
=> #<refinement:String@A>
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 `<main>'

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

Actions

Also available in: Atom PDF