in reply to Correct idiom for default parameters

if you are restricted to positional parameters, what about this ...

sub defaults { my $d1= ( @_ ? shift : 1 ); my $d2= ( @_ ? shift : 2 ); my $d3= ( @_ ? shift : 3 ); print("$d1 $d2 $d3\n"); } defaults(); defaults(0); defaults(0, 0); defaults(0, 0, 0); __DATA__ 1 2 3 0 2 3 0 0 3 0 0 0

Cheers Rolf

UPDATE: precedence rules allow to omit the parens.

UPDATE from the example you gave I assumed that you don't plan to pass undef in the middle of parameters and expect this to be checked... otherwise all these solutions are too simplified and you have to check explicitly with defined. But in this case I really recommend using named parameters!

Replies are listed 'Best First'.
Re^2: Correct idiom for default parameters
by LanX (Saint) on Apr 28, 2010 at 20:37 UTC
    more condensed:

    sub defaults { my ($d1,$d2,$d3) = map { @_ ? shift : $_ } (1,2,3); print("$d1 $d2 $d3\n"); } defaults(); defaults(0); defaults(0, 0); defaults(0, 0, 0);

    plz note: this solution depends on the number of defaulted parameters...

    Cheers Rolf

      That looks pretty good!

      And to answer your question in the post previous to this one, no I don't expect there to be an "undef" in the middle. The overwhelming majority of the cases there is one parameter that is optional. Which means that the predominant use will look like this:

      sub defaults { my ($self, $param) = map { @_ ? shift : $_ } (1); print($param); }

      I found one place where it would be nice to have two optional parameters, but I'm debating refactoring that sub routine.

        >  my ($self, $param) = map { @_ ? shift : $_ } (1);

        ehm ... $self defaults to 1??? ;-)

        IMHO better catch $self in a separate shift!

        UPDATE:

        > The overwhelming majority of the cases there is one parameter that is optional. Which means that the predominant use will look like this:

        Then better avoid this construct!

        IMHO it's much clearer (and faster) to write

        my ($self,$a,$b,$c,$d)=@_; $d = 4 unless defined $d;

        Cheers Rolf

Re^2: Correct idiom for default parameters
by LanX (Saint) on Apr 28, 2010 at 20:52 UTC
    for completeness:

    you can even slice lists ...

    sub defaults { my ($d1,$d2,$d3) = ( @_ , (1,2,3)[@_ .. 2] ); print("$d1 $d2 $d3\n"); } defaults(); defaults(0); defaults(0, 0); defaults(0, 0, 0);

    but I don't like that the maximum index has to be hard coded.

    at least this solution doesn't destroy @_ ...

    Cheers Rolf