Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

default values for lists

by pike (Monk)
on Sep 17, 2002 at 15:00 UTC ( #198502=perlquestion: print w/replies, xml ) Need Help??
pike has asked for the wisdom of the Perl Monks concerning the following question:

I often use default values for scalar variables, e. g.

$val = $x || $default

Now I tried this for lists, but it doesn't work - or, to be precise, it works only if the first list is empty, because otherwise the first list is interpreted in scalar context:

@a = (); @b = qw (one two three); @c = qw (four five); @d = @a || @c; #gives ('four', 'five') - OK @d = @b || @c; #gives ('3') - yikes!

Can I inhibit the interpretation of the first list as scalar? Or is the only way to get the desired behaviour:

@list = @a; @list = @default unless @list;

Thanks for your suggestions,


Replies are listed 'Best First'.
Re: default values for lists
by fglock (Vicar) on Sep 17, 2002 at 15:03 UTC
    try this:  @d = @a ? @a : @c;
      OK, maybe I should have given more context: I was trying to strip of the ending of words, do something with the words and put the ending back on, like this:

      my ($end) = $word =~ /(e?s)$/ || (''); ... #do something with $word $word = "$word$end";

      If the word does not end in s/es, I get a warning about uninitialized variables where I append $end - which I wanted to avoid.

      I thought about the ternary, but I don't want to evaluate the regex twice.

      I simplified the problem because IMO it boils down to the question if I can enforce list context on the part before the ||. But maybe I oversimplified it.

      Thanks anyway for the suggestion.


        Ah, ok. Try this:

        ($begin, $end) = $word =~ /(.*?)(es|s|)$/;
        Then I'd say my $end = $word =~ /(e?s)$/ ? $1 : '';

        Makeshifts last the longest.

Re: default values for lists
by Elgon (Curate) on Sep 17, 2002 at 15:09 UTC

    Hi pike,

    You could try using the trinary operator...

    @d = @a ? @a : @c;

    In the example given, if @a returns true (in scalar context ie. has a nonzero length) then it is copied into @d, otherwise the contents of @c are copied into @d.

    Update: Arrgh, fglock beat me to it!

    "Rule #17 of Travel: Never try and score dope off Hassidic Jews while under the impression that they are Rastafarians."
           - Pete McCarthy, McCarthy's Bar

Re: default values for lists
by RMGir (Prior) on Sep 17, 2002 at 15:12 UTC
    There are a few options I can see. If it's completely "either @a or @default", or if you want all of @a, and fill in with the first few from @default if @a is short, then you could do this:
    As an alternative, you could do:
    @list=map {$_>$#a ? $default[$_] : $a[$_] } 0..$#default;
    It's a lot easier to do default values if you use hashes, though.
Re: default values for lists
by blokhead (Monsignor) on Sep 17, 2002 at 17:42 UTC
    Assuming I've not misintepreted your question, I'd lean towards a solution something like this:
    my @defaults = qw/one two three four five/; my @a = qw/un deux trois/; $a[$_] ||= $defaults[$_] for (0 .. $#defaults); print "@a\n"; # prints "un deux trois four five"
    Again, if you're looking for a completely either-or approach to the two lists, then the aforementioned trinary operator is probably the best choice. If you want to take from @a or @defaults on a per-element basis, then the trinary operator won't give you the desired results -- you'll need to use an approach like mine or RMGir's above.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://198502]
Approved by Elgon
Tanktalus books his flight, starts getting nervous.
holli tries to remember where he put that Stinger-II leftover from Afghanistan

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2017-09-22 20:09 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (268 votes). Check out past polls.