Assigning default values to function arguments which may be "empty" In perl, is there a canonical practice or idiom for assigning value to an argument which, if "empty", is assigned a default value?

Here, "empty" is defined as an argument value which is either undef or the null string (''). Notably, 0 (or perl false) is a valid, non-"empty" value, which rules out the construction $min_perl_version = (shift ||= '5.008009').

This is my current construction (note the use of the v5.10+ logical-or operator, //):

my $min_perl_version = do {$_ = shift // q{}; (length) ? $_ : '5.008009'};


as in the example function:


sub is_CORE { # ( $:MIN_PERL_VERSION , $:MODULE )
    use 5.008009; # perl v5.8.9; required for Module::CoreList to be available in CORE
    my $min_perl_version = do {$_ = shift // q{}; (length) ? $_ : '5.008009'}; # "empty" =&gt; default to version 5.008009
    my $module = shift;
    return ($Module::CoreList::VERSION &gt;= 2.99) &amp;&amp; Module::CoreList::is_core($module, undef, $min_perl_version);
}


I don't want warnings or to duplicate the use of the default value.

Is there a simpler / more elegant solution, say... without a named temporary variable?

A succinct solution which is functional back to earlier perl versions (5.6 or 5.8) would be a plus as well.

edit: for clarity

For clarification, the function interface and definition of argument validity (eg, what "empty" means) are set constants. While I appreciate any critique, a conversation about the line:

my $min_perl_version = do {$_ = shift // q{}; (length) ? $_ : '5.008009'};


and how it might be better coded is the real point of the question.
use 5.008009 is insufficient here, since you're using the // operator, which was introduced in Perl 5.10.

This function feels awkwardly designed.  Generally, parameters that have default values appear after all required parameters.  Here, I would need to explicitly pass in undef as the first parameter to take advantage of the default.  Also note that the parameters for your is_CORE are backwards relative to Module::CoreList::is_core.

I also don't understand the benefit of having the empty string trigger the default.  I can understand having undef trigger the default.  I could also agree with having all "falsy" values trigger the default.  But this particular design feels weird.  If I had to do it, though, I'd write it like this:

sub is_CORE {
    use 5.008009; # perl v5.8.9; required for Module::CoreList to be available in CORE
    my ($module, $min_perl_version) = @_;
    $min_perl_version = '5.008009' unless defined $min_perl_version &amp;&amp; length $min_perl_version;
    $Module::CoreList::VERSION &gt;= 2.99 &amp;&amp; Module::CoreList::is_core($module, undef, $min_perl_version);
}