Project

General

Profile

Feature #12593

Allow compound assignements to work when destructuring arrays

Added by najamelan (Naja Melan) over 3 years ago. Updated about 3 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:76395]

Description

a = [ 'a', 'b' ]
b = [ 'c', 'd' ]

def c

    return [ 'A', 'B' ], [ 'C', 'D' ]

end

a, b += c # -> would be awesome, but gives syntax error

a, b = a + c.first, b + c.last # clunky and will call method twice...

# current realistic use:
t, tt = c
a += t
b += tt

# desired result
#
p a == [ 'a', 'c', 'A', 'B' ] #-> true
p b == [ 'b', 'd', 'C', 'D' ] #-> true

I would propose that as

a, b = [ c, d ] # is equivalent to:
a = c 
b = d

a, b += [ c, d ] # would be equivalent to:
a += c
b += d

This not working surprised me. It could work with all compound assignment operators I think. Maybe even with some other operators.

History

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

The problem is, parallel assignment can go ultra complex. Its left hand and right hand side not necessarily are arrays, or not always come in same count. a, b = 1, [2], "3", :'4' is a valid ruby code; there seems no reason to forbid a, b += 1, [2], "3", :'4', or even, a, b += 1.

One could think of behaviours of such assignments, but I doubt if there are reasonable definitions for all pitfall-ish situations.

Updated by najamelan (Naja Melan) over 3 years ago

What I propose is to translate the construct:

a = 3
b = [ 2 ]

a, b = 2, 3, 4

a == 2
b == 3

# 4 is ignored

a, b = 2

a == 2
b == nil

That's current behaviour if the number of elements is not the same on both sides.

a,b += 2, 3, 4

# translates to:

a = a + 2
b = b + 3 # `+': no implicit conversion of Fixnum into Array (TypeError)

# 4 is ignored.


a, b += 2

a = a + 2
b = b + nil

If you just translate the statement, There is is no special case to take into account, the interpreter will just do it's job on the translated statement.

Obviously you have to make special accomodation for everything that you want to work:

if a, b < c, d     # would become:

if a < c && b < d  # then && is arbitrary, matter of convention, that someone has to decide on.

but whatever wouldn't work because nobody has wanted to implement it, well it already doesn't work today, so that's no change then.

Updated by matz (Yukihiro Matsumoto) about 3 years ago

  • Status changed from Open to Rejected

I am not going to make multiple assignments even more complex.
The behavior of OP_ASGN for multiple assignments is not obvious.

Matz.

Also available in: Atom PDF