Feature #5735

Extending the use of splat operator to when it is inside a hash

Added by Tsuyoshi Sawada over 2 years ago. Updated over 1 year ago.

[ruby-dev:44962]
Status:Feedback
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:-
Target version:next minor

Description

Ruby convention of allowing omittion of the curly brackets for the last argument is convenient:

foo(arg1, arg2, 1 => :a, 2 => :b)

Sometimes, I want to pass a hash with some modifications. For example, suppose h = {3 => :c, 4 => :d, 5 => :e} is a hash already defined and that I want to add some key-value pairs as well as overwrite some values of h, such as {3 => :c, 4 => :f, 5 => :e, 6 => :g}, and pass that. The current convention only allows:

foo(arg1, arg2, h.merge(4 => :f, 6 => :g))

but it would be more convenient if a hash preceded by the splat operator is placed in a hash, it is interpreted as part of the hash, allowing notations like:

foo(arg1, arg2, *h, 4 => :f, 6 => :g)

or, if I want to overwrite the hash {4 => :f, 6 => :g} with h, then:

foo(arg1, arg2, 4 => :f, 6 => :g, *h)

Or besides the argument position, in general, usages like the following:

{3 => :h, *h, 4 => :f, 6 => :g}

This is an analogy from the splat operator used within an array:

[1, 2, *[4, 5, 6], 7, 8]

History

#1 Updated by George Koehler over 2 years ago

=begin
Ruby trunk has a hash splat operator because of feature #5474, keyword argument. See ((URL:http://bugs.ruby-lang.org/issues/5474)).

With this version of Ruby,

ruby 2.0.0dev (2012-01-04 trunk 34211) [x86_64-openbsd5.0]

I can run this code,

def eat(i: 1, **hash)
printf "i is %p, hash is %p\n", i, hash
end
eat(h: 7, i: 8, j: 9)
# => "i is 8, hash is {:h=>7, :j=>9}"

So far, *hash only works when defining a method. We cannot (yet) use *hash in a method call or a hash literal.

args = {h: 2, i: 3, j: 4}
eat(*args) # syntax error!
args = {k: 5, *
args} # syntax error!

There is much more discussion of hash splat at feature #5474.
=end

#2 Updated by Yusuke Endoh about 2 years ago

  • Status changed from Open to Feedback
  • Assignee set to Yukihiro Matsumoto

Marc-Andre proposed a similar idea at , and Matz commented a little at .
It would be good to investigate how many use cases occur in real world.

matz wrote:

I am still not sure if we need hash splat nor hash decomposition, it
might be useful in some cases, but also makes syntax more complex.
So we need more discussion before picking it.

But if we could made consensus I'd make small changes to proposed
syntax.

For hash splat, I'd rather use ** instead of *, because splat in array
and splat in hash are different. Using same operator could cause
confusion. Besides that, I would also restrict hash splat position to
the end, since hashes do not have order.

Yusuke Endoh mame@tsg.ne.jp

#3 Updated by Yusuke Endoh over 1 year ago

  • Target version set to next minor

Also available in: Atom PDF