Lambda regression between 2.4.0 and 2.4.1


(Paul Martensen) #1

Hi there!

I think I might have found a regression (unless someone can point me to the commit that states this is expected).
Look at the following if you will:

print_three = ->(a, b, c) { puts [a, b, c] }
arr = [[1, 2, 3]]

arr.map(&print_three)

This works on ruby-2.4.0 but breaks from ruby-2.4.1 onwards (ArgumentError).

On 2.4.1 you have to use explicit destructuring: print_three = ->((a, b, c)) { puts [a, b, c] }

Is this intended behaviour and can anyone of you replicate this?

Happy Coding,
Paul Martensen


(Eli Sadoff) #2

Hi Paul,

Using RVM here are my results with some different version of ruby

*1.9.3 (Does not work)*
→ ruby -v
ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-darwin16.7.0]

→ ruby print_three.rb
print_three.rb:1:in `block in <main>': wrong number of arguments (1 for 3)
(ArgumentError)
    from print_three.rb:4:in `map'
    from print_three.rb:4:in `<main>'

*2.1.1 (Does not work)*
→ ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin12.0]

→ ruby print_three.rb
print_three.rb:1:in `block in <main>': wrong number of arguments (1 for 3)
(ArgumentError)
    from print_three.rb:4:in `map'
    from print_three.rb:4:in `<main>'

*2.2.8 (Works -- NEW)*
→ ruby -v
ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin17]

# esadof772 at HQSML-C1SMGTFM in ~ [10:41:33]
→ ruby print_three.rb
1
2
3

*2.3.3 (Works)*
→ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]

→ ruby print_three.rb
1
2
3

*2.4.0 (Works)*
→ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin17]

→ ruby print_three.rb
1
2
3

*2.4.1 (Does not work -- REGRESSION from 2.4.0)*→ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin17]

→ ruby print_three.rb
print_three.rb:1:in `block in <main>': wrong number of arguments (given 1,
expected 3) (ArgumentError)
    from print_three.rb:4:in `map'
    from print_three.rb:4:in `<main>'

*2.4.2 (Does not work)*
→ ruby -v
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]

→ ruby print_three.rb
print_three.rb:1:in `block in <main>': wrong number of arguments (given 1,
expected 3) (ArgumentError)
    from print_three.rb:4:in `map'
    from print_three.rb:4:in `<main>'

*2.5.0 (Does not work)*→ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17]

→ ruby print_three.rb
Traceback (most recent call last):
    2: from print_three.rb:4:in `<main>'
    1: from print_three.rb:4:in `map'
print_three.rb:1:in `block in <main>': wrong number of arguments (given 1,
expected 3) (ArgumentError)

- Eli Sadoff

Hope this helps

···

On Wed, Mar 28, 2018 at 4:42 AM, Paul Martensen <paul.martensen@gmx.de> wrote:

Hi there!

I think I might have found a regression (unless someone can point me to
the commit that states this is expected).
Look at the following if you will:

print_three = ->(a, b, c) { puts [a, b, c] }
arr = [[1, 2, 3]]

arr.map(&print_three)

This works on ruby-2.4.0 but breaks from ruby-2.4.1 onwards
(ArgumentError).

On 2.4.1 you have to use explicit destructuring: print_three = ->((a, b,
c)) { puts [a, b, c] }

Is this intended behaviour and can anyone of you replicate this?

Happy Coding,
Paul Martensen

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>


(Dmitriy Non) #3

Hi!

I don't know if this is a bug, but I actually would expect ArgumentError
since lambda works as method (so it does not use implicit destructurization).

Have you tried to look for this issue in changelogs?

By the way:

# ruby 2.3.6
def f(a, b, c)
 a
end

g = ->(a, b, c) { a }

[[1, 2, 3]].map(&method(:f)) # ArgumentError
[[1, 2, 3]].map(&g) # 1 

def test_block(&block)
 block.call([1, 2, 3])
end

def test_yield
 yield([1, 2, 3])
end

test_block(&g) # ArgumentError
test_yield(&g) # 1

I think that `yield` treats Proc as "true" block (Proc just a wrapper over blocks).
And in Ruby 2.4.1+ this behaivior was changed to be more obvious (at least I think it is so)

···

--------------------------------------
Dmitriy Non
non.dmitriy@gmail.com

On 28 Mar 2018, at 11:42, Paul Martensen <paul.martensen@gmx.de> wrote:

Hi there!

I think I might have found a regression (unless someone can point me to the commit that states this is expected).
Look at the following if you will:

print_three = ->(a, b, c) { puts [a, b, c] }
arr = [[1, 2, 3]]

arr.map(&print_three)

This works on ruby-2.4.0 but breaks from ruby-2.4.1 onwards (ArgumentError).

On 2.4.1 you have to use explicit destructuring: print_three = ->((a, b, c)) { puts [a, b, c] }

Is this intended behaviour and can anyone of you replicate this?

Happy Coding,
Paul Martensen

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>