Project

General

Profile

Actions

Bug #15285

closed

lambda return behavior regression from #14639

Added by nmueller (Nate Mueller) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
[ruby-core:89734]

Description

The change in ea15ceddbef2cc4c459c1ad5796e43ae9fa2cbf1 to use rb_yield_force_blockarg changes the behavior of returns called inside a passed lambda function. In 2.5.1 and below, including before the enum.c change, the attached script would print true. In 2.5.3 it prints false.


Files

test.rb (118 Bytes) test.rb nmueller (Nate Mueller), 11/06/2018 09:19 PM
test.rb (828 Bytes) test.rb jhawthorn (John Hawthorn), 11/19/2018 10:41 PM

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #14639: Array#map and lambda arity regressionClosedActions
Actions #1

Updated by shyouhei (Shyouhei Urabe) over 5 years ago

  • Related to Bug #14639: Array#map and lambda arity regression added

Updated by shyouhei (Shyouhei Urabe) over 5 years ago

ea15ceddbef2cc4c459c1ad5796e43ae9fa2cbf1 is r64996, which is a backport of r63030, which fixes #14639.

@nobu (Nobuyoshi Nakada) any idea?

Updated by jhawthorn (John Hawthorn) over 5 years ago

I also ran into this problem in ruby 2.5.3.

This is a little confusing because there are two things being changed here:

  1. How arguments are handled in a passed &lambda, which was asked for in #14639
  2. How return is handled in a passed &lambda

I attached a test script to help demonstrate

In ruby 2.3, the passed lambda will always splat the arguments (the lambda treats arguments like a block), but return only returns from the lambda

2.3.7
Array#map
  args    ✅
  return  ✅ lambda return semantics
Enumerable#map
  args    ✅
  return  ✅ lambda return semantics
Array#each
  args    ✅
  return  ✅ lambda return semantics
Array#map!
  args    ✅
  return  ✅ lambda return semantics

In ruby 2.4, the passed lambda now treats arguments like a normal lambda (it won't splat them). I think this is a good change (but that could be a debate). This is the complaint in #14639

2.4.4
Array#map
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics
Enumerable#map
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics
Array#each
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics
Array#map!
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics

In ruby 2.5.3 and in 2.6.0-preview3, Array#map was changed to always treat the passed lambda as a block. This changed both how it treats arguments (the desired change) and how it treats return (this bug).

In addition, it only made this change to Array#map aka Array#collect, which now doesn't match similar methods like Enumerable#map or Array#each or Array#map!. It's also a weird behaviour to have since it would be hard to write a custom MyClass#map in ruby which behaved the same way.

2.6.0
Array#map
  args    ✅
  return  ❌ block return semantics
Enumerable#map
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics
Array#each
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics
Array#map!
  args    💣 wrong number of arguments (given 1, expected 2)
  return  ✅ lambda return semantics

I think both r64996 (for 2.5.x) and r63030 should be reverted.

Actions #4

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r65923.


Revert r63030

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0