Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: conditional statements in list constructors

by kcott (Bishop)
on Mar 27, 2014 at 14:48 UTC ( #1079937=note: print w/replies, xml ) Need Help??

in reply to conditional statements in list constructors

G'day Don Coyote,

if may be used as a Compound Statement or as a Statement Modifier. It is not an operator.

Placing an if statement in a do block, as you show, can emulate the ternary operator but, as is fairly obvious, results in clunky code with poor readability and maintainability.

So, if introduces a compound statement (or statement modifier) and ?: is an operator. They are not synonymous. With do blocks, parentheses, and other syntactical tricks, you can usually (if not always) replace one with the other; however, this is typically not a good idea. [For more on this, see "Re: Code blocks with ternary operator or trailing conditionals", which I wrote a few weeks ago.]

The ternary operator can be used in any list, not just to generate an array, so an improvement on the print examples you show, might be (using equivalent code):

print 1<2 ? '1' : '2', $/;

Although, perhaps a more likely scenario might be something like:

$ perl -Mstrict -Mwarnings -e ' for my $item_count (0..2) { print "$item_count item", $item_count == 1 ? "" : "s", ".\n" } ' 0 items. 1 item. 2 items.

When using the ternary operator, take care with precedence issues and add parentheses where needed (the documentation shows some examples).

A final point, unrelated to conditionals, regarding your test:

my $arrref = \( if(1<2){'1'}else{()} );

Taking a reference to a list actually returns a list of references to each item in the original list. Accordingly, it would probably be a good idea to avoid any instances of:

$arrayref = \(...);

While that may work when first written using a list with only one item, any subsequent modifications which result in additional list items will cause problems. A better option would be:

$arrayref = [...];

Item 2. of "perlref: Making References" has more information on this.

-- Ken

Replies are listed 'Best First'.
Re^2: conditional statements in list constructors
by AnomalousMonk (Bishop) on Mar 27, 2014 at 15:10 UTC
    Taking a reference to a list actually returns a list of references to each item in the original list. ... probably ... good ... to avoid ...:

    $arrayref = \(...);


    c:\@Work\Perl\monks>perl -wMstrict -le "my $not_really_an_arrayref = \('one', 'two', 'three'); print $$not_really_an_arrayref; " three

      Good point; however, the way you'd normally dereference an arrayref generates a fatal runtime error:

      $ perl -le ' my $think_this_is_an_arrayref = \(qw{one two three}); print qq{Probably not dereference like this: $$think_this_is_an_ar +rayref}; print qq{Probably would dereference like this: @$think_this_is_an_ +arrayref}; ' Probably not dereference like this: three Not an ARRAY reference at -e line 4.

      -- Ken

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1079937]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2022-05-27 22:21 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (98 votes). Check out past polls.