Wazery
Wazery

Reputation: 15863

Pass Ruby 2 keyword arguments without specifying them explicitly

How I can pass the keyword arguments to a call to another method in my code without specifying each of them.

Consider the following method with the new first-class support for kwargs:

def foo(obj, bar: 'a', baz: 'b')
  another_method(bar, baz)
end

Consider the old Ruby options hash syntax:

def foo(obj, options = {})
  another_method(options)
end

I want to pass the keyword arguments without specifying each of them explicitly as with the case of the old options hash syntax. Is that even possible?

Upvotes: 3

Views: 1216

Answers (2)

Edward Loveall
Edward Loveall

Reputation: 2253

Keyword arguments work similarly to your "old Ruby options hash syntax". A hash's keys will substitute as keywords and their values as arguments. This should work fine:

def foo(obj, bar: 'a', baz: 'b')
  another_method(bar, baz)
end

arg_hash = { bar: 'alt bar', baz: 'alt baz' }

foo(Object.new, arg_hash)

Some things to be aware of

If your hash keys are strings, such as { 'bar' => 'alt bar', 'baz' => 'alt baz' }, this won't work. You'll get an ArgumentError: wrong number of arguments (2 for 1) error. This is easy enough to fix in Rails by calling .symbolize_keys on the hash. If you're not in Rails, you'll have to convert the keys manually or reimplement that method.

Also, in Rails, a HashWithIndifferentAccess (such as the params hash in a controller), although it has both strings and symbols for keys, can't be used in this way. If you pass params, it will look at the string keys instead and you'll get the same error as above. I'm not sure why this is the case, but my guess it's because the params hash starts with strings and adds symbols so the symbols are secondary and not the default. Total guess on that though.

Upvotes: 0

Doguita
Doguita

Reputation: 15703

You can use the double-splat operator:

def a(q: '1', w: '2')
  p q
  p w
end

def b(**options)
  a(options)
end

b
# => 1
# => 2

b(q: '3', w: '4')
# => 3
# => 4

Upvotes: 3

Related Questions