Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

exit this way

by ExReg (Priest)
on Aug 31, 2015 at 21:29 UTC ( [id://1140564]=perlquestion: print w/replies, xml ) Need Help??

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

I am adding several perl scripts and modules to an existing set of perl tools. When they looked over my latest script, they said that I should have an exit statement at the end, before all the subs. I do not see the need for exit if the script completes normally. Comments?

Replies are listed 'Best First'.
Re: exit this way
by AnomalousMonk (Archbishop) on Aug 31, 2015 at 22:34 UTC

    Further to Your Mother's reply: Because Perl has no  main() function and allows intermixing function calls and definitions, strange things can happen. Better by far, IMHO, to have someone put in a function call and scratch their head (even for quite a while) about why it is never executed than to have the code compile and apparently run correctly for hours/days/weeks/... before realizing that, hey, something ain't right! Here's an (admittedly rather contrived) example of goofy behavior:

    c:\@Work\Perl\monks>perl -wMstrict -le "S(3); T(); S(9); T(); ;; exit_here_to_avoid_weirdness(); ;; my $x = 42; sub S { $x = $_[0]; printf qq{in S: x == $x }; T(); } ;; sub T { ++$x; print qq{in T: x == $x}; } ;; sub exit_here_to_avoid_weirdness { ;;; } T(); " in S: x == 3 in T: x == 4 in T: x == 5 in S: x == 9 in T: x == 10 in T: x == 11 in T: x == 43
    Is that 43 result from the last call to  T() correct? Maybe better not to make it at all:
    c:\@Work\Perl\monks>perl -wMstrict -le "S(3); T(); S(9); T(); ;; exit_here_to_avoid_weirdness(); ;; my $x = 42; sub S { $x = $_[0]; printf qq{in S: x == $x }; T(); } ;; sub T { ++$x; print qq{in T: x == $x}; } ;; sub exit_here_to_avoid_weirdness { exit; } T(); " in S: x == 3 in T: x == 4 in T: x == 5 in S: x == 9 in T: x == 10 in T: x == 11
    (Of course, it would be nice to have a "code not reachable" message, but that's life.)


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

      it would be nice to have a "code not reachable" message

      There isn't such a check for post-exit(), but Perl::Critic definitely has a rule for pre-use strict;. I guess one could write a rule that ignored subroutines...

      I guess there is!

      The way forward always starts with a minimal test.
      This will probably become a standards issue, and I will probably start putting the exits in. I hate it when I have to abide by standards that I get after others about. I know I would never leave stray bits of code roaming around after the subs start. ;^)
Re: exit this way
by stevieb (Canon) on Aug 31, 2015 at 21:45 UTC

    Ask for their rationale for this. There's no need for an explicit exit unless you literally need to explicitly exit prior to the end of your code.

    For instance:

    my $x = $y; # short circuit exit if $x == 1; # do other stuff ...

    Besides, if you have all of your subs underneath of your code that calls them, that may confuse future maintainers as to why there is a random exit; in the middle of the code. Also, if someone goes and adds more code later after the sub definitions and doesn't see the random exit somewhere above, they'll be scratching their head as to why their code is failing to execute. It's better (imho) to ensure all of the code runs properly unless there's a good reason to exit early.

      Thanks. This was my thought on the matter.

        Well, you’re right. Right in the same way that there is no particular reason use strict; is necessary to working code. An exit; or exit 0; between your code and your subs is an excellent practice and can prevent goofy and accidental bugs.

Re: exit this way ( END block will be executed )
by 1nickt (Canon) on Sep 01, 2015 at 15:31 UTC

    I'm agnostic about the many recommendations here to follow the practice your overlords are seeking to impose. But if you do so, remember that exit() doesn't always exit immediately ...

    #!/usr/bin/perl use strict; use warnings; use feature qw/ say /; main(); exit(0); sub main { say 'Exiting'; } END { say 'Not done yet'; }
    Output:
    $ perl 1140667.pl Exiting Not done yet $

    The way forward always starts with a minimal test.
Re: exit this way
by karlgoethebier (Abbot) on Sep 06, 2015 at 19:12 UTC
    "...they looked over my latest script...said that I should have an exit statement at the end, before all the subs. I do not see the need for exit..."

    I've been told to do this a while ago.

    If "they" insist give them their fu****g main AKA block and this exit, it doesn't hurt:

    #!/usr/bin/env perl use strict; use warnings; use feature qw(say); MAIN: { say karl(); exit 0; } sub karl { qq(nose); } __END__

    I hope i guessed right. Else sorry ;-) Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

Re: exit this way
by sundialsvc4 (Abbot) on Sep 01, 2015 at 13:57 UTC

    Another strategy that I have sometimes seen used goes something like this:

    #!/usr/bin/perl exit main(); sub main { ... }

    Even though the Perl language does not have the concept of a main() subroutine, these authors created one, and ensured that only it would be executed.   An interesting idea ...

      This seems like a mistake or a bad practice in Perl. exit codes are a complete mismatch for subroutine return expectations. I suppose something like this might work but still… I say, nay. Also neigh.

      #!/usr/bin/env perl exit ! main(); sub main { $success = [ undef, "true" ]->[rand 2] }

        Boiler plate code for the build scripts in our build system looks like:

        package main; my $build = BuildGeneral->new(buildtype => 'release'); exit(!$build || $build->runFailed());

        which often causes a double take at first glance, but accurately reflects the sense of the exit value.

        Premature optimization is the root of all job security

        Hi, Your Mother. Can you please explain this snippet? It does print out the randomly assigned value of $success if I change it to:

        exit ! main(); sub main { $success = [ undef, "true" ]->[rand 2]; print "$success\n" +}
        But it appears to produce the same output when I omit the !:
        exit main(); sub main { $success = [ undef, "true" ]->[rand 2]; print "$success\n" +}
        Which appears to be the same code as The Vague One posted ...

        What is the function of the bang?

        The way forward always starts with a minimal test.

        In many other languages, main is "special". The unnamed programmers were attempting to make a facsimile of that "specialness".

        Perhaps:

        #!perl use strict; use warnings; main(); exit 99; # or other reasonable default exit value

        might be better.

Re: exit this way
by hsmyers (Canon) on Sep 06, 2015 at 16:54 UTC
    Nope. No way. Not even if you make my cold dead fingers type it in. In my book, anything that increases white noise in code is bad. So I certainly don't. Shop standards? If it were optional I could certainly tolerate it, but if it were to be required I'd protest and ignore it.

    --hsm

    "Never try to teach a pig to sing...it wastes your time and it annoys the pig."

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-19 06:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found