Project

General

Profile

Backport #8153

Problems with Enumerable#zip caused by overriding Object#respond_to?

Added by mjtko (Mark Titorenko) over 6 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Normal
[ruby-core:53650]

Description

If I override Object#respond_to? under Ruby 2.0.0, Enumerable#zip begins to misbehave. Here is the code and output in Ruby 2.0.0:

2.0.0p0 :001 > RUBY_VERSION
=> "2.0.0"
2.0.0p0 :002 > class Object
2.0.0p0 :003?> alias :_respond_to? :respond_to?
2.0.0p0 :004?> def respond_to?(*a)
2.0.0p0 :005?> _respond_to?(*a)
2.0.0p0 :006?> end
2.0.0p0 :007?> end
=> nil
2.0.0p0 :008 > [1,2,3].zip((1..3).each)
=> [[1, nil], [2, nil], [3, nil]]

Should be: [[1, 1], [2, 2], [3, 3]]

Here is the output I was expecting, generated in Ruby 1.9.3 -- ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-darwin12.2.0]:

1.9.3p392 :001 > RUBY_VERSION
=> "1.9.3"
1.9.3p392 :002 > class Object
1.9.3p392 :003?> alias :_respond_to? :respond_to?
1.9.3p392 :004?> def respond_to?(*a)
1.9.3p392 :005?> _respond_to?(*a)
1.9.3p392 :006?> end
1.9.3p392 :007?> end
=> nil
1.9.3p392 :008 > [1,2,3].zip((1..3).each)
=> [[1, 1], [2, 2], [3, 3]]
1.9.3p392 :009 >

I'm not certain if this is the only method which is interfered with, but it's how I determined an issue was present initially.

For copy and paste convenience:

class Object
alias :_respond_to? :respond_to?
def respond_to?(*a)
_respond_to?(*a)
end
end

[1,2,3].zip((1..3).each)

FWIW, the same behaviour occurs if using a prepend-ed module and super:

module RespondToBug
def respond_to?(*a)
super
end
end

class Object
prepend RespondToBug
end


Related issues

Related to Backport200 - Backport #8154: Remove/fix rb_check_block_callClosed03/23/2013Actions

Associated revisions

Revision cb0093d5
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39877 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 39877
Added by marcandre (Marc-Andre Lafortune) over 6 years ago

  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

Revision 04c9bdb1
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39881 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 39881
Added by nobu (Nobuyoshi Nakada) over 6 years ago

vm_eval.c: preserve passed_block

  • vm_eval.c (check_funcall_respond_to): preserve passed_block, which is modified in vm_call0_body() via vm_call0(), and caused a bug of rb_check_funcall() by false negative result of rb_block_given_p(). re-fix [ruby-core:53650] [Bug #8153]. [ruby-core:53653] [Bug #8154]

Revision 59f8d5d1
Added by nagachika (Tomoyuki Chikanaga) about 6 years ago

merge revision(s) 39877,39881: [Backport #8153] [Backport #8154]

    * array.c: Avoid zip bug by not using obsolete rb_check_block_call
      [Bug #8153]

    * vm_eval.c (check_funcall_respond_to): preserve passed_block, which
      is modified in vm_call0_body() via vm_call0(), and caused a bug of
      rb_check_funcall() by false negative result of rb_block_given_p().
      re-fix [ruby-core:53650] [Bug #8153].
      [ruby-core:53653] [Bug #8154]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40281 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 40281
Added by nagachika (Tomoyuki Chikanaga) about 6 years ago

merge revision(s) 39877,39881: [Backport #8153] [Backport #8154]

* array.c: Avoid zip bug by not using obsolete rb_check_block_call
  [Bug #8153]

* vm_eval.c (check_funcall_respond_to): preserve passed_block, which
  is modified in vm_call0_body() via vm_call0(), and caused a bug of
  rb_check_funcall() by false negative result of rb_block_given_p().
  re-fix [ruby-core:53650] [Bug #8153].
  [ruby-core:53653] [Bug #8154]

History

Updated by drbrain (Eric Hodel) over 6 years ago

Is respond_to_missing? insufficient for your needs?

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Category set to core
  • Assignee set to marcandre (Marc-Andre Lafortune)

Indeed, using respond_to_missing? is typically the preferred way, but that's a very odd bug!

#3

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39877.
Mark, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]
#4

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Tracker changed from Bug to Backport
  • Project changed from Ruby trunk to Backport200
  • Category deleted (core)
  • Status changed from Closed to Open
  • Assignee changed from marcandre (Marc-Andre Lafortune) to nagachika (Tomoyuki Chikanaga)

Updated by mjtko (Mark Titorenko) about 6 years ago

Thanks, glad to hear this has been fixed!

As for using respond_to_missing? - I understand the purpose of respond_to_missing? but, in my case, I was explicitly overriding respond_to? in order to try and track down bad code that was still using the single-argument version for determining the presence of protected methods. This was working fine, but instead was causing other code to fail with the zip bug as outlined above. :)

#6

Updated by nagachika (Tomoyuki Chikanaga) about 6 years ago

  • Status changed from Open to Closed

This issue was solved with changeset r40281.
Mark, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 39877,39881: [Backport #8153] [Backport #8154]

* array.c: Avoid zip bug by not using obsolete rb_check_block_call
  [Bug #8153]

* vm_eval.c (check_funcall_respond_to): preserve passed_block, which
  is modified in vm_call0_body() via vm_call0(), and caused a bug of
  rb_check_funcall() by false negative result of rb_block_given_p().
  re-fix [ruby-core:53650] [Bug #8153].
  [ruby-core:53653] [Bug #8154]

Also available in: Atom PDF