What is the point of using a double Ruby character (`**`) in method calls?

With one splat, we can expand the array into several arguments, which is very different from passing the array directly:

def foo(a, b = nil, c = nil) a end args = [1, 2, 3] foo(args) # Evaluates to foo([1, 2, 3]) => [1, 2, 3] foo(*args) # Evaluates to foo(1, 2, 3) => 1 

With the keyword arguments, however, I see no difference, since they are just syntactic sugar for hashes:

 def foo(key:) key end args = { key: 'value' } foo(args) # Evaluates to foo(key: 'value') => 'value' foo(**args) # Evaluates to foo(key: 'value') => 'value' 

Besides good symmetry, is there a practical reason to use double signs when calling a method? (Note that this is different from using them when defining a method)

+6
source share
1 answer

A single argument example is a degenerate case.

Looking at a non-trivial case, you can quickly see the advantage of the new operator ** :

 def foo (args) return args end h1 = { b: 2 } h2 = { c: 3 } foo(a: 1, **h1) # => {:a=>1, :b=>2} foo(a: 1, **h1, **h2) # => {:a=>1, :b=>2, :c=>3} foo(a: 1, h1) # Syntax Error: syntax error, unexpected ')', expecting => foo(h1, h2) # ArgumentError: wrong number of arguments (2 for 1) 

Using the ** operator allows us to combine existing hashes on the command line with literal key arguments. (The same goes for using * with arrays of arguments, of course.)

Unfortunately, you have to be careful with this behavior, depending on which version of Ruby you are using. In Ruby 2.1.1, at least there was a bug in which the smoothed hash would be destroyed in a way , although it was fixed.

+5
source

All Articles