Project

General

Profile

Bug #16504

`foo(*args, &args.pop)` should pass all elements of args

Added by mame (Yusuke Endoh) about 1 month ago. Updated about 1 month ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]
[ruby-core:96798]

Description

https://bugs.ruby-lang.org/issues/16500?next_issue_id=16499&prev_issue_id=16501#note-7

# in 2.7
args = [1, 2, -> {}]; foo(   *args, &args.pop) #=> passes [1, 2] (bug; [1, 2, ->{}] is expected)
args = [1, 2, -> {}]; foo(0, *args, &args.pop) #=> passes [0, 1, 2, ->{}] (good)

Related issues

Related to Ruby master - Bug #16500: Argument is added to both splat and last &block argumentOpenioquatix (Samuel Williams)Actions
Related to Ruby master - Bug #12860: Splatting an argument does not obey left-to-right execution orderClosedActions
#2

Updated by mame (Yusuke Endoh) about 1 month ago

  • Related to Bug #16500: Argument is added to both splat and last &block argument added

Updated by Eregon (Benoit Daloze) about 1 month ago

What's the definition of foo here?

I believe the previous behavior is the block expression gets evaluated before the rest of the arguments.
We should decide and clarify if the block or positional arguments are evaluated first.

If I see foo(*args, &args.pop) I would expect no duplicated arguments.
I believe that's the previous and more intuitive behavior.
I'd be happy if we can warn it though, because that code is really unreadable.

foo(*args, &args.last) should be used if wanting to pass the last argument both as block and last positional.

Updated by mame (Yusuke Endoh) about 1 month ago

Okay, I'll ask matz which is right. But I believe that the 2.6 and current behavior is wrong because Ruby has a principle of left-to-right evaluation. Actually, foo(*ary, ary.pop) was changed between 2.1 and 2.2; 2.2 and later duplicate the last argument. And what do you think about foo(*ary, 42, &ary.pop)?

#5

Updated by mame (Yusuke Endoh) about 1 month ago

  • Related to Bug #12860: Splatting an argument does not obey left-to-right execution order added

Updated by Eregon (Benoit Daloze) about 1 month ago

Agreed left-to-right would be far more consistent.

We just need to be aware that whoever writes foo(*args, &args.pop) probably expects no duplication (so they would disagree on "bug" probably).
But such code deserves to be clearer IMHO.

Updated by marcandre (Marc-Andre Lafortune) about 1 month ago

mame (Yusuke Endoh) wrote:

Okay, I'll ask matz which is right. But I believe that the 2.6 and current behavior is wrong because Ruby has a principle of left-to-right evaluation.

For sure current behavior is wrong and left-to-right evaluation must be observed.

Also available in: Atom PDF