I am able to define a method like this:
def test(id, *ary, hash_params)
# Do stuff here
end
But this makes the hash_params
argument mandatory. These don't work either:
def t(id, *ary, hash_params=nil) # SyntaxError: unexpected '=', expecting ')'
def t(id, *ary, hash_params={}) # SyntaxError: unexpected '=', expecting ')'
Is there a way to make it optional?
@Casper is right. Only one of the parameters can have the splat operator. Arguments get assigned to the non-splatted parameters first left-to-right. Remaining arguments get assigned to the splat parameter.
You can do as he suggest. You can also do this:
Here are some sample irb runs:
Perhaps, I should add. You CAN have an optional parameter as the last parameter but it must be a block/proc.
For example:
Here are some sample calls:
There is support for this in ActiveSupport through the use of the array extension
extract_options!
.If the last element is a hash, then it will pop it from the array and return it, otherwise it will return an empty hash, which is technically the same as what you want
(*args, opts={})
to do.ActiveSupport Array#extract_options!
You can't do that. You have to think about how Ruby would be able to determine what belongs to
*ary
and what belongs to the optional hash. Since Ruby can't read your mind, the above argument combination (splat + optional) is impossible for it to solve logically.You either have to rearrange your arguments:
In which case
h
will not be optional. Or then program it manually:You could (mis-)use the optional block at the end of the parameter list:
In addition to caspers answer:
You may use a splash parameter and check, if the last parameter is a hash. Then you take the hash as settings.
A code example:
Result is:
This will make problems, if your array-parameter should contain a hash at last position.
Result: