The following code loops endlessly:
use strict; use warnings; use File::Spec::Functions "devnull"; sub bar { open my $fh, "< $_[0]" or die "couldn't open $_[0]: $!"; print while <$fh>; } sub foo { for (@_) { bar(devnull()) } } $. = 0; foo($.);
Do you see why? This is an especially bad variant on the common while-loop inside for smashing aliased $_ problem, which usually elicits a couple of points: But here, there's something else going on. A magic variable $. is being passed around; only its value is actually wanted, but instead, the container of the value is given. This can lead to trouble. Consider this case:
use strict; use warnings; use Data::Dumper; $Data::Dumper::Terse=1; sub foo { print "foo: bad args: ", Dumper \@_ if @_ != 2 || $_[0] !~ /^[tf]/ || $_[1] !~ /statement/; my ($tf, $statement) = @_; if ($tf =~ /^t/) { # Line 12 print "true: $statement\n"; } else { print "false: $statement\n" } } for my $statement ("the following statement is true", "the preceding statement is false") { $statement =~ /\b(t|f|true|false)\b/ or next; foo($1, $statement); }
Here, I am calling foo("true", "the following statement is true"); and foo("false", "the following statement is false");, but by the time foo gets to line 12, $tf is not set to the passed parameter. The container $1 was passed, and before it was assigned to $tf, an intervening regex undefined it. (However, because $1 is dynamically scoped, once foo() returns, $1 will again be "true" or "false".)

The moral here is to beware action at a distance; when passing magic variables, or even your own globals, if you want them passed by value, explicitly stringify or numify them:

foo(0+$.); # and foo("$1", $statement);
so that the callee gets the value at the time of the call.

In reply to Passing globals and magic variables safely by ysth

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.