From: alex@... Date: 2014-03-13T12:34:01+00:00 Subject: [ruby-core:61461] [ruby-trunk - Bug #9605] Chaining "each_with_index.detect &lambda" raises ArgumentError Issue #9605 has been updated by Alex Rothenberg. Finally found another implementation that behaves identically to MRI. RubyMotion acts the same with "each_with_index.map" accepting 2 args while "each_with_index.detect" raises an ArgumentError. ~~~ $ rake Build ./build/iPhoneSimulator-7.1-Development Compile ./app/app_delegate.rb Create ./build/iPhoneSimulator-7.1-Development/test.app Link ./build/iPhoneSimulator-7.1-Development/test.app/test Create ./build/iPhoneSimulator-7.1-Development/test.app/PkgInfo Create ./build/iPhoneSimulator-7.1-Development/test.app/Info.plist Copy ./resources/Default-568h@2x.png Create ./build/iPhoneSimulator-7.1-Development/test.dSYM Simulate ./build/iPhoneSimulator-7.1-Development/test.app (main)> [1].each(&lambda{p :ng}) 2014-03-13 08:05:41.185 test[13295:70b] wrong number of arguments (1 for 0) (ArgumentError) => # (main)> [1].each(&->(){p :ng}) 2014-03-13 08:05:48.836 test[13295:70b] wrong number of arguments (1 for 0) (ArgumentError) => # (main)> [1].each_with_index.map(&->(x,i){p [x,i].inspect}) "[1, 0]" => ["[1, 0]"] (main)> [1].each_with_index.detect(&->(x,i){p [x,i].inspect}) 2014-03-13 08:06:26.346 test[13295:70b] wrong number of arguments (1 for 2) (ArgumentError) => # ~~~ Also the 4 cases with lambdas and lambdas convereted to blocks all raise ArgumentError. ~~~ (main)> def test (main)> yield 1 (main)> end => :test (main)> test(&lambda{p :ng}) 2014-03-13 08:28:38.975 test[13295:70b] wrong number of arguments (1 for 0) (ArgumentError) => # (main)> test(&->(){p :ng}) 2014-03-13 08:28:50.617 test[13295:70b] wrong number of arguments (1 for 0) (ArgumentError) => # (main)> def test(l) (main)> l.call(1) (main)> end => :test (main)> test(&lambda{p :ng}) 2014-03-13 08:29:08.934 test[13295:70b] wrong number of arguments (0 for 1) (ArgumentError) => # (main)> test(&->(){p :ng}) 2014-03-13 08:29:17.132 test[13295:70b] wrong number of arguments (0 for 1) (ArgumentError) => # ~~~ ---------------------------------------- Bug #9605: Chaining "each_with_index.detect &lambda" raises ArgumentError https://bugs.ruby-lang.org/issues/9605#change-45756 * Author: Alex Rothenberg * Status: Rejected * Priority: Normal * Assignee: * Category: * Target version: * ruby -v: 2.1.1 * Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN ---------------------------------------- I found an odd edge case where "detect" and "select" behave differently from other methods of Enumerable. Normally these methods yield a single argument to a block but when you chain them after "each_with_index" they yield two arguments "item" and "index". The problem is when you try passing a lambda instead of a block then they raise an ArgumentError $ irb 2.1.1 :001 > lambda = ->(word, index) { word.length == 3 } => # 2.1.1 :002 > %w(Hi there how are you).each_with_index.detect &lambda ArgumentError: wrong number of arguments (1 for 2) from (irb):1:in `block in irb_binding' from (irb):2:in `each' from (irb):2:in `each_with_index' from (irb):2:in `each' from (irb):2:in `detect' from (irb):2 from /Users/alex/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `
' 2.1.1 :003 > %w(Hi there how are you).each_with_index.select &lambda ArgumentError: wrong number of arguments (1 for 2) from (irb):1:in `block in irb_binding' from (irb):3:in `each' from (irb):3:in `each_with_index' from (irb):3:in `each' from (irb):3:in `select' from (irb):3 from /Users/alex/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `
' Interestingly it works just find when calling other methods like "map" 2.1.1 :004 > %w(Hi there how are you).each_with_index.map &lambda => [false, false, true, true, true] It also works when you use a proc 2.1.1 :001 > proc = Proc.new {|word, index| word.length == 3 } => # 2.1.1 :002 > %w(Hi there how are you).each_with_index.detect &proc => ["how", 2] 2.1.1 :003 > %w(Hi there how are you).each_with_index.map &proc => [false, false, true, true, true] or a block 2.1.1 :001 > %w(Hi there how are you).each_with_index.detect {|word, index| word.length == 3 } => ["how", 2] 2.1.1 :002 > %w(Hi there how are you).each_with_index.map {|word, index| word.length == 3 } => [false, false, true, true, true] When testing against JRuby or Rubinius none of these scenarios raise an ArgumentError. I'm guessing this is a bug and not intended behavior. If it is intended then both those implementations have a bug in not raising ArgumentError. -- http://bugs.ruby-lang.org/