Project

General

Profile

Bug #15808

Forwardable doesn't allow forwarding the 'print' message

Added by kyrylo (Kyrylo Silin) over 1 year ago. Updated over 1 year ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin17]
[ruby-core:92464]

Description

The following program forwards two messages to @foo: message 'print' and message 'bar'.
When I forward the 'print' message, I see a warning and the return value of print is always nil
(despite the fact that I specified my own return value).
When I forward the 'bar' message, it works as expected (I see the return value of 'bar').

require 'forwardable'
require 'ostruct'

class A
  extend Forwardable
  def_delegators :@foo, :print, :bar

  def initialize(foo)
    @foo = foo
  end
end

obj = A.new(OpenStruct.new(print: 123, bar: 456))

p "print - #{obj.print}; bar - #{obj.bar}" 
forwardable_bug.rb:15: warning: A#print at /Users/kyrylo/.rubies/ruby-2.6.0/lib/ruby/2.6.0/forwardable.rb:158 forwarding to private method OpenStruct#print
"print - ; bar - 456"

Files

forwardable_bug.rb (250 Bytes) forwardable_bug.rb kyrylo (Kyrylo Silin), 04/28/2019 04:01 PM

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

  • Status changed from Open to Rejected

This is not a bug in Forwardable, this is due to the fact that OpenStruct doesn't override print, as Kernel#print is already defined. You must undefine the print method in OpenStruct if you want this to work. Example:

require 'forwardable'
require 'ostruct'

class A
  extend Forwardable
  def_delegators :@foo, :print, :bar

  def initialize(foo)
    @foo = foo
  end
end

os = OpenStruct.new(print: 123, bar: 456)
os.method(:print).owner
# => Kernel
os.singleton_class.send(:undef_method, :print)
os.method(:print).owner
=> #<Class:#<OpenStruct:0x00000038d756dc80>>
obj = A.new(os)

p "print - #{obj.print}; bar - #{obj.bar}" 
# "print - 123; bar - 456"

Also available in: Atom PDF