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

Compound statements within the conditional (ternary) operator

by Fendo (Novice)
on Apr 14, 2018 at 12:04 UTC ( [id://1212866]=perlquestion: print w/replies, xml ) Need Help??

Fendo has asked for the wisdom of the Perl Monks concerning the following question:

Hello wise monks! I come to ask for your kind advice and enlightenment on the following matter:

I've been trying to print a character a certain number of times, if a certain condition is met. For the printing, I use an “until” loop. For the condition, I would like to use the conditional (ternary) operator. However, this apparently results in a syntax error. Below is example code which produces the error. My intention was to print the equals sign ten times instead.

#!/usr/bin/perl use strict; use warnings; my $count = 0; ( defined $count ) ? ( print "=" until ( $count ++ == 10 ) ) : ( print "Undefined count.\n" );

This results in the error: syntax error at ./example.pl line 8, near ""=" until". I have tried using a different form for the loop:

( defined $count ) ? ( until ( $count ++ == 10 ) { print "=" } ) : ( print "Undefined count.\n" );

However, that results in a similar error: syntax error at ./example.pl line 8, near "( until". When I try to achieve this using “if” and “else”, it works very well, using this code:

if ( defined $count ) { print "=" until ( $count ++ == 10 ); } else { print "Undefined count.\n"; }
Is it possible to use such constructions within the conditional (ternary) operator, as I've been trying to do? And if yes, how may I do so correctly? Thank you in advance!

Replies are listed 'Best First'.
Re: Compound statements within the conditional (ternary) operator (updated)
by AnomalousMonk (Archbishop) on Apr 14, 2018 at 12:27 UTC

    The basic problem is that you're trying to give  ?: a statement where the operator expects an expression. Try something like these:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $count; F(); ;; $count = 0; F(); ;; sub F { defined $count ? do { print '=' until $count ++ == 5; } : print 'Undefined count' ; } " Undefined count = = = = = c:\@Work\Perl\monks>perl -wMstrict -le "my $count; F(); ;; $count = 0; F(); ;; sub F { print defined $count ? '=' x 5 : 'Undefined count'; } " Undefined count =====
    The second example does not keep track in  $count of the number of  '=' characters printed and you may need this for some reason, but if you don't, the second example is the way I'd go.

    Update: If you do want to keep track of the number of things printed, here's a variation on the second method:

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my $count; F(); dd $count; ;; $count = 0; F(); dd $count; ;; sub F { print defined $count ? '=' x ($count += 5) : 'Undefined count'; } " Undefined count undef ===== 5


    Give a man a fish:  <%-{-{-{-<

Re: Compound statements within the conditional (ternary) operator
by roboticus (Chancellor) on Apr 14, 2018 at 19:52 UTC

    Fendo:

    You've already got some good answers, but in the spirit of "we've a plethora of ways to do it", you could simply compute the number of "=" signs that you want, and then build a list of them like this:

    print defined($count) ? ("=") x (10-$count) : "Undefined count.\n";

    Of course, if you calculate the number of "=" symbols you want, then you could also do it as:

    print defined($count) ? substr("==========", $count) : "Undefined count.\n";

    However, once you try it, you'll notice that your printing is off because you're sometimes putting in a "\n" and sometimes not. If you want to always put in the "\n", you could do it like:

    print defined($count) ? ("=") x (10-$count) : "Undefined count.", "\n"; print defined($count) ? substr("==========", $count) : "Undefined count.", "\n";

    You could crunch them up into a single line, too:

    print defined($count) ? ("=") x (10-$count) : "Undefined count.", "\n" +; print defined($count) ? substr("==========", $count) : "Undefined coun +t.", "\n";

    but then it's easy to miss that there are two expressions generating arguments for the print statement and/or easy to confuse the boundary between them.

    Sometimes, though, it just simplifies things overall to break things apart a bit. Most of the time, I'd simply do something like:

    if (! defined $count) { print "Undefined count.\n" } else { print substr("==========", $count) }

    But I do see the natural desire to make the printing front-and-center rather than the conditional logic. I'll frequently do so when the logic is pretty basic:

    print "You bought $qty item", $qty>1 ? "s" : "", " today!\n";

    But when there's too much logic in formatting something to print, it's often better to do the decisioning earlier, then assemble the bits into your print statement:

    my $item = $qty > 1 ? "items" : "item"; my $num = num_to_text($qty); my $when = "today"; $when = "yesterday" if $purchase_date == $yesterday; print "You bought $num $item $when!\n";

    Sigh ... I think I'll stop now, or I'll go off on another tangent...

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      A minor nit: I don't know about other Englishes, but for Yank-Canuck and I think Brit English usage, I would construct the plural slightly differently:

      c:\@Work\Perl\monks>perl -wMstrict -le "for my $qty (0 .. 3) { printf qq{you bought $qty item%s today \n}, $qty == 1 ? '' : 's'; } " you bought 0 items today you bought 1 item today you bought 2 items today you bought 3 items today


      Give a man a fish:  <%-{-{-{-<

        AnomalousMonk:

        Yep, if $qty kan be naught, then yer code would be more Englishy. ;^)

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: Compound statements within the conditional (ternary) operator
by mr_ron (Chaplain) on Apr 14, 2018 at 13:02 UTC

    Mostly what AnomalousMonk said. The first paragraph on ?: in Programming Perl (4th ed) talks about it being an operator and expression similar to if-then-else which is a flow control statement. A hopefully simpler example:

    use Modern::Perl; my $count = 0; print defined $count ? do { my $s = ''; $s .= '=' until $count++ == 10; $s } : "Undefined count.\n";
    Ron

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1212866]
Approved by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-04-26 08:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found