squale squale - 7 months ago 19
Perl Question

Strict vs non-strict: Which instance of a named variable gets used?

I am trying to find the problem and propose a solution for the following Perl code.

A file without

strict
nor
warnings
on it has a function that uses a
$variable
without declaring it. So that variable is global to the file and the changes for that variable in this specific function are used outside of it (since it is global for the file).

Due to a recent update, this
old_file
now
requires
a modified version of itself (
new_file
) in which the same function is defined. But this new version has
strict
and
warnings
, so the same variable is defined, but this time as 'my' in the new function, and is returned in the end.

The tricky thing is that the code in the
old_file
did not change so it still expects the variable to be changed as its own global variable.

Since I don't know Perl well enough to be able to determine which version of this function is used (and since I can't test it, due to IT restrictions) I need an explanation of the behavior, possibly a link to a good paper about that topic.

Code: (I think the problem is in the variable
LISTEREPONSE
from the function
start_handler
.)

old_file:

use XML::Parser;
my $parser = new XML::Parser( ErrorContext => 2 );
$parser->setHandlers(
Start => \&start_handler,
End => \&end_handler,
Char => \&char_handler
);
$parser->parse(<$remote>);

close $remote;
...
sub start_handler {
my $expat = shift;
my $element = shift;
print;

while (@_) {
my $att = shift;
my $val = shift;
$LISTEREPONSE .= "$att=$val&";
}
}


new_file:

sub start_handler {
my $expat = shift;
my $element = shift;
print;
my $LISTEREPONSE;

while (@_) {
my $att = shift;
my $val = shift;
$LISTEREPONSE .= "$att=$val&";
}
return $LISTEREPONSE;
}

Answer

In strict mode, if you need $LISTEREPONSE become a global variable in package(file) scope.

Just declare (my $LISTEREPONSE;) in the beginning of file (after use).

In second case, $LISTEREPONSE is declare in sub, it's lexical scope and only available in sub.

my $LISTEREPONSE;
# ...
sub some_sub {
    $LISTEREPONSE .= $some_stuff;
}