Project

General

Profile

Feature #6414

Destructuring Assignment

Added by edtsech (Edward Tsech) about 5 years ago. Updated over 4 years ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
[ruby-core:44951]

Description

I mean:

john = {name: "John", last: "Smith"}
{name, last} = john # extract value by key from the hash and set to local variable with same name
name # => "John"
last # -> "Smith"

Useful for ex. for "options" hashes:
def select(options={})
{only, except} = options
...
end

As extra part of this feature can be hash constructing in this way:

name = "John"
last = "Smith"
find({name, last}) # equals to => find({name: "John", last: "Smith"})

I think both really nice to have in Ruby.
Thanks.

destructuring.pdf (128 KB) marcandre (Marc-Andre Lafortune), 07/01/2012 06:26 AM


Related issues

Related to Ruby trunk - Feature #5474: keyword argument Closed 10/23/2011

History

#1 [ruby-core:45088] Updated by mame (Yusuke Endoh) about 5 years ago

  • Status changed from Open to Assigned
  • Assignee set to matz (Yukihiro Matsumoto)

FYI: There is similar (but not same) proposal:

--
Yusuke Endoh mame@tsg.ne.jp

#2 [ruby-core:46019] Updated by marcandre (Marc-Andre Lafortune) almost 5 years ago

Attaching a one-minute slide. It doesn't cover the "construction" part of this request though.

#3 [ruby-core:46054] Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 5 years ago

-1. I'd still like to see Ruby supporting CoffeeScript hash style for this common pattern:

Instead of
a = 1; b = 2; c = {a: a, b: b}

I'd prefer to write just c = {a, b}. The current proposed syntax wouldn't allow such a feature in the future.... :(

By the way, I can't remember what is the current situation of an old proposition to allow things like {"#{interpolation}": value} as well as {'some string': value}.

Was it already accepted? Is there already a slide for it?

#4 [ruby-core:46082] Updated by mame (Yusuke Endoh) almost 5 years ago

Marc-Andre, your slide is received. Thank you!

Rodrigo, I don't know CoffeeScript, but what is the difference between OP's (second) proposal and yours?

name = "John"
last = "Smith"
find({name, last}) # equals to => find({name: "John", last: "Smith"})

Instead of
a = 1; b = 2; c = {a: a, b: b}
I'd prefer to write just c = {a, b}.

--
Yusuke Endoh mame@tsg.ne.jp

#5 [ruby-core:46143] Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 5 years ago

sorry but I couldn't find the proposal you're talking about, but looking at the examples it seems there is no difference.

But one thing that is supported in CoffeeScript and is not in the examples is to mix both forms. For example, in Ruby, that would mean:

b = 2; d = 4
{a: 1, b, 'c' => 3, d } == { :a => 1, :b => b, 'c' => 3, :d => d }

#6 [ruby-core:46669] Updated by mame (Yusuke Endoh) almost 5 years ago

Edward Tsech and Marc-Andre Lafortune,

We discussed your slide at the developer meeting (7/21).

We were not sure if we can actually implement this feature in terms
of yacc. Could you create an experimental patch?

Matz was basically positive to the feature itself, but wanted to
focus on surely implementable syntax (with no parser conflict and
with reasonable code).

--
Yusuke Endoh mame@tsg.ne.jp

#7 Updated by trans (Thomas Sawyer) almost 5 years ago

So this is a shortcut for?

name, last = john.values_at(:name, :last)

If so, long ago it was suggested Hash#[] support multiple keys:

name, last = john:name, :last

Not as short as {name, last} = john, but not quite as esoteric either.

If assigning from an array can work, eg.

john = ['John', 'Smith']
name, last = john

Why not hash? So, just

john = {:name=>'John', :last=>'Smith'}
name, last = john

#8 [ruby-core:46685] Updated by cjheath (Clifford Heath) almost 5 years ago

On 24/07/2012, at 2:20 AM, trans (Thomas Sawyer) wrote:

If so, long ago it was suggested Hash#[] support multiple keys:

name, last = john:name, :last

I'm very glad this didn't happen. I often have reason to use arrays as hash keys,
and this would make that impossible.

Clifford Heath.

#9 [ruby-core:46693] Updated by trans (Thomas Sawyer) almost 5 years ago

I made a mistake with that example.

name, last = john[:name, :last]

#10 [ruby-core:46707] Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 5 years ago

I'd much prefer something like this and reserve the {a, b} syntax to be used as a shortcut for {a: a, b: b} like in CoffeeScript in the future...

Also, I find it clearer to read as well

#11 [ruby-core:46708] Updated by shyouhei (Shyouhei Urabe) almost 5 years ago

  • Status changed from Assigned to Feedback
  • Assignee deleted (matz (Yukihiro Matsumoto))

This request won't progress without a working proof-of-concept. Feel free to send us your pull request. https://github.com/ruby/ruby

#12 [ruby-core:48246] Updated by yhara (Yutaka HARA) over 4 years ago

  • Target version changed from 2.0.0 to Next Major

#13 [ruby-core:48248] Updated by yhara (Yutaka HARA) over 4 years ago

  • Target version changed from Next Major to next minor

Also available in: Atom PDF