Good explanation. I'd suggest adding something that explicitly explains how to
avoid this problem.
The basic solution is to wrap all top-level code that isn't inside a subroutine
in a new sub, and then fixing all the problems with global variables.
In this case, something like:
use strict;
use warnings;
main(); # <----- change
+ here
sub main { # <----- change
+ here
my $foo = 5;
print "Content-type: text/plain\n";
print "Content-disposition: inline; filename=foo.txt\n\n";
printf "Package: %s\n", __PACKAGE__;
printf "[%s] Before: %s\n", $$, $foo;
badness(5);
printf "[%s] After: %s\n", $$, $foo;
} # <----- change
+ here
sub badness {
my $val = shift;
printf "[%s] badness: %s\n", $$, $foo;
$foo += $val;
}
That will not run, so we need to fix the reference to $foo in
badness:
use strict;
use warnings;
main();
main();
main();
sub main {
my $foo = 5;
print "Content-type: text/plain\n";
print "Content-disposition: inline; filename=foo.txt\n\n";
printf "Package: %s\n", __PACKAGE__;
printf "[%s] Before: %s\n", $$, $foo;
badness(5, $foo); # <----- change
+ here
printf "[%s] After: %s\n", $$, $foo;
}
sub badness {
my $val = shift;
our $foo; # <----- clever
+ trick here(*)
local *foo = \shift; # <-
printf "[%s] badness: %s\n", $$, $foo;
$foo += $val;
}
Real-life scripts will probably be harder, so make sure to run
perl -c your_script.pl early and often :^)
Update: As ikegami pointed out, using my $foo = shift in badness runs, but it
doesn't act the same. The (*)clever trick suggested by ikegami is a good way to circumvent that.
Later iterations should probably move to a more functional approach, by making the subroutines free
of side effects.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.