I have seen a particular code smell with default parameters. That is when a method has a default value set for one of its params but the caller passes nil
instead of passing no value. In most cases, this is because the caller has a hash and it tries to pass a particular value from the hash. Specifically:
def foo(params)
...
bar(params[:first], params[:second]) # :second doesn't exist
end
def bar(first, second = 2)
end
The second param to foo
doesn't not become the default value but becomes nil
. The most common way I have seen this handled is that the first line within the function bar is:
second ||= 2
Is there a better way of handling this? That is, whenever nil
or no param gets passed, assign a default value.
def bar(first, second = 2)
This sets second
to 2
if the argument omitted. nil
is a value with a meaning, so passing nil
as the value for argument is explicitly telling it to be nil
. This is on purpose, so you can override the default with nil
if you want.
If you want your argument to assign a default if it is omitted or nil
, then ||=
is the idiomatic way to do it.
def bar(first, second = nil)
second ||= 2
puts second
end
bar 1 #=> 2
bar 1, 3 #=> 3
bar 1, nil #=> 2
the second = nil
allows you to omit the argument, and assigns a default of nil
. And if the argument is nil
you can set it to a real default. This means that passing in nil
and omitting the argument is now essentially the same thing.
It doesn't behave this way universally because sometime you want to replace a default argument with nil
. And the way default arguments works allows you to do just that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With