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: <%-{-{-{-<
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
|
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. ;^)
| [reply] [Watch: Dir/Any] |
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Thanks. This was my thought on the matter.
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
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»
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: exit this way
by sundialsvc4 (Abbot) on Sep 01, 2015 at 13:57 UTC
|
#!/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 ...
| [reply] [Watch: Dir/Any] [d/l] |
|
#!/usr/bin/env perl
exit ! main();
sub main { $success = [ undef, "true" ]->[rand 2] }
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
#!perl
use strict;
use warnings;
main();
exit 99; # or other reasonable default exit value
might be better.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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."
| [reply] [Watch: Dir/Any] |