Reputation: 806
Let's say we have the following subroutine:
sub test($arg = 'defaut value') { say $arg }
And we want to pass some argument that will cause the subroutine to use the default value, something like this:
my $undefined-value;
test $undefined-value // Nil; # don't work, prints "Nil"
How to accomplish this in the most idiomatic way possible?
I found this solution, but it looks a bit hacky:
test |($undefined-value // Empty); # works, print "defaut value"
Upvotes: 4
Views: 94
Reputation: 26979
I guess the most idiomatic way is to:
sub test($arg? is copy) {
$arg //= 'default value';
say $arg;
}
test Any; # default value
which would allow you to pass any undefined value as the argument
Alternately, you could use a multi:
multi sub test(Any:U $) { test }
multi sub test(Any:D $arg = "default value") { say $arg }
test Any; # default value
The first candidate will catch any undefined value, and then call the candidate without any arguments, which will then set the default value.
Please note that there is a subtle(?) difference between the two solutions; there are some values which will be considered missing in the first solution but present in the second (including Empty
). (If you are curious about the details, see the concepts of "defined" - which backs the former solution - and "DEFINITE" - which backs the latter solution.)
Upvotes: 4