Choice between ", exit if" and "and exit if"

8 views
Skip to first unread message

Henry Law

unread,
Mar 16, 2021, 11:47:01 AMMar 16
to
I often want to check some condition and if it's true execute one simple
statement and then bale out. Written out "long hand" it might be

if ( $mistakes > 2 ){
print "There are too many mistakes\n";
exit;
}

I routinely code it more succinctly like this:

print "There are too many mistakes\n" and exit if $mistakes > 2;

But I've also occasionally copied another formulation, with the comma
operator rather than 'and':

print "There are too many mistakes\n", exit if $mistakes > 2;

I see from "perlop" that 'and' is of lower precedence than ',' but that's
not important because I only have one of them; and they're both left-
associative. The comma evaluates the "print" (which is always true) and
then evaluates the "if"; whereas the 'and' operator computes first the
left hand side (doing the print) and then if it's true (which it is) the
"if". Both of these are what I want.

Can someone explain to me why these are different, if indeed they are,
and which if either is preferable?

--
Henry Law n e w s @ l a w s h o u s e . o r g
Manchester, England

Keith Thompson

unread,
Mar 16, 2021, 12:44:43 PMMar 16
to
There's different because "and" is affected by the result of the print.
Don't assume that print is always successful. (For example, on my
system I can make it fail by redirecting output to "/dev/full".) Even
if you can assume it will always succeed, using "and" says explicitly
that you want your program's behavior to depend on whether print
succeeds or fails.

I don't think you want your program to continue running only if the
print was unsuccessful.

In your example, printing error messages to stdout is probably a bad
idea. The "die" function prints to stderr and terminates the program:

die "There are too many mistakes\n" if $mistakes > 2;

But if that really is the behavior you want, I'd use the comma operator
rather than "and". Or I might write something like this:

do { print "There are too many mistakes\n"; exit } if $mistakes > 2;

Or I might write a small function:

sub die_stdout {
print @_;
exit;
}

die_stdout("There are too many mistakes\n") if $mistakes > 2;

Or, frankly, I'd just write the block. I might consider writing the
whole thing on one line if it's a small throwaway piece of code *or* if
it's part of a sequence of similar statements:

if ($mistakes > 2) { print "There are too many mistakes\n"; exit; }
if ($goofs > 3) { print "There are too many goofs\n"; exit; }
# ...

Again, I wouldn't write error messages to stdout, and "die" is designed
for this, but perhaps that aspect wasn't central to what you're asking.

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

Henry Law

unread,
Mar 16, 2021, 2:24:04 PMMar 16
to
On Tue, 16 Mar 2021 09:44:35 -0700, Keith Thompson wrote:

> Even
> if you can assume it will always succeed, using "and" says explicitly
> that you want your program's behavior to depend on whether print
> succeeds or fails.

Quite so; I hadn't thought of that.

> In your example, printing error messages to stdout is probably a bad
> idea. The "die" function prints to stderr and terminates the program:

Indeed; if I'd coded "return", which is actually more likely in my code,
it would have made it clear.

That's very clear, thank you Keith, and given me some things to think
about.

Rainer Weikusat

unread,
Mar 16, 2021, 6:29:15 PMMar 16
to
Henry Law <ne...@lawshouse.org> writes:

[...]

> print "There are too many mistakes\n", exit if $mistakes > 2;

Tangential issue: This exits with a status code of 0 whose usual meaning
is "it worked". Using an error status code (anything except 0) is
probably a better idea here.

Randal L. Schwartz

unread,
Mar 17, 2021, 2:23:24 AMMar 17
to
>>>>> "Rainer" == Rainer Weikusat <rwei...@talktalk.net> writes:

Rainer> Tangential issue: This exits with a status code of 0 whose usual
Rainer> meaning is "it worked". Using an error status code (anything
Rainer> except 0) is probably a better idea here.

Which is why I use "die" far more often than I use "exit".

print "Just another Perl hacker,";

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Dart/Flutter consulting, Technical writing, Comedy, etc. etc.
Still trying to think of something clever for the fourth line of this .sig

Randal L. Schwartz

unread,
Mar 17, 2021, 2:23:35 AMMar 17
to
>>>>> "Henry" == Henry Law <ne...@lawshouse.org> writes:

Henry> I routinely code it more succinctly like this:

Henry> print "There are too many mistakes\n" and exit if $mistakes > 2;

Henry> But I've also occasionally copied another formulation, with the
Henry> comma operator rather than 'and':

Henry> print "There are too many mistakes\n", exit if $mistakes > 2;

Henry> I see from "perlop" that 'and' is of lower precedence than ','
Henry> but that's not important because I only have one of them; and
Henry> they're both left- associative. The comma evaluates the "print"
Henry> (which is always true) and then evaluates the "if"; whereas the
Henry> 'and' operator computes first the left hand side (doing the
Henry> print) and then if it's true (which it is) the "if". Both of
Henry> these are what I want.

No, in this case, because print is gathering a list, which includes the
"result" of the exit invocation, nothing will get printed, because the
exit will have already executed. Common mistake to have things nearby a
list-gathering function.

Now, if you had written this:

print("There are too many mistakes\n"), exit if $mistakes > 2;

it would work more like you're thinking it does.

print "Just another Perl hacker,"; # the original JAPH!

Rainer Weikusat

unread,
Mar 17, 2021, 10:12:02 AMMar 17
to
mer...@stonehenge.com (Randal L. Schwartz) writes:
>>>>>> "Rainer" == Rainer Weikusat <rwei...@talktalk.net> writes:
>
> Rainer> Tangential issue: This exits with a status code of 0 whose usual
> Rainer> meaning is "it worked". Using an error status code (anything
> Rainer> except 0) is probably a better idea here.
>
> Which is why I use "die" far more often than I use "exit".

"die" would be much more useful if it would support formatted output à
la printf and didn't have the annoying habit of mangling its arguments
with all kinds "I'm sure you'll want that!" stuff.

The most "ease of use" situation I've encountered in this respect so far
is "the appendix is annoying but this doesn't matter that
much". Usually, I end up writing code to get rid of it.

$Bill

unread,
Mar 17, 2021, 12:40:07 PMMar 17
to
On 03/17/2021 07:11, Rainer Weikusat wrote:
>
> "die" would be much more useful if it would support formatted output à
> la printf and didn't have the annoying habit of mangling its arguments
> with all kinds "I'm sure you'll want that!" stuff.

Just slip a sprintf in after the die and you've got it. ;)

Henry Law

unread,
Mar 19, 2021, 11:54:01 AMMar 19
to
On Tue, 16 Mar 2021 23:03:23 -0700, Randal L. Schwartz wrote:

> No, in this case, because print is gathering a list, which includes the
> "result" of the exit invocation, nothing will get printed, because the
> exit will have already executed. Common mistake to have things nearby a
> list-gathering function.

Perfect! A very clear explanation of what I didn't understand.

Randal L. Schwartz

unread,
Mar 20, 2021, 1:43:17 AMMar 20
to
>>>>> "Henry" == Henry Law <ne...@lawshouse.org> writes:


Henry> Perfect! A very clear explanation of what I didn't understand.

I *do* have a fair amount of practice at explaining things... Perl in
particular. :)

print "Just another Perl hacker,"; # the original

Henry Law

unread,
Mar 20, 2021, 6:01:10 AMMar 20
to
On Fri, 19 Mar 2021 22:35:37 -0700, Randal L. Schwartz wrote:

> I *do* have a fair amount of practice at explaining things... Perl in
> particular.

Well I wonder why that might be. Nevertheless, the gift of the
instructor is to perceive the thought errors of the student and to
choose, from a vast lexicon of possible explanations, the correct form of
words to effect correction. Not everybody who "knows a lot of stuff" has
that gift also.
Reply all
Reply to author
Forward
0 new messages