[ruby-core:38799] to_ary not respecting respond_to?

2 views
Skip to first unread message

Ryan Davis

unread,
Aug 4, 2011, 6:37:01 PM8/4/11
to ruby...@ruby-lang.org
class BadProxyObject
def initialize
@p = Object.new
def @p.to_ary
raise "I should never be called"
end
end

def respond_to?(*a)
p :bad_respond_to? => a
false
end

def method_missing(msg, *)
p :bad_method_missing => msg
@p.send msg
end
end

[[BadProxyObject.new]].flatten

# {:bad_method_missing=>:to_ary}
# Exception `RuntimeError' at wtf.rb:6 - I should never be called
# wtf.rb:6:in `to_ary': I should never be called (RuntimeError)
# from wtf.rb:17:in `method_missing'
# from wtf.rb:21:in `flatten'
# from wtf.rb:21:in `<main>'

Extra Info: http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/


Adam Prescott

unread,
Aug 5, 2011, 6:04:06 AM8/5/11
to ruby...@ruby-lang.org
And I've just seen that http://redmine.ruby-lang.org/issues/5158 has been opened and closed. Too slow, I guess.

Adam Prescott

unread,
Aug 5, 2011, 6:06:47 AM8/5/11
to ruby...@ruby-lang.org
On Thu, Aug 4, 2011 at 11:37 PM, Ryan Davis <ryand...@zenspider.com> wrote:
Extra Info: http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/

Someone made a comment on that post linking to http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/ which explains, specifically for Array#flatten:

----

In Ruby 1.8, the process is essentially the following:

if obj.respond_to?(:to_ary)
  obj.__send__(:to_ary)
else
  obj
end

In Ruby 1.9, it was changed to:

begin
  obj.__send__(:to_ary)
rescue NoMethodError
  obj
end

----

I'm not sure why that changed happened, but at least that seems to be the source of the behaviour.

Michael Edgar

unread,
Aug 5, 2011, 6:09:13 AM8/5/11
to ruby...@ruby-lang.org
On Aug 5, 2011, at 6:06 AM, Adam Prescott wrote:

I'm not sure why that changed happened, but at least that seems to be the source of the behaviour.

I believe it happened because respond_to? is unreliable in the presence of
method_missing unless a lot of care is taken, and that care is rarely taken.

Reply all
Reply to author
Forward
0 new messages