Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^3: Leaking Function Return

by haukex (Abbot)
on Oct 06, 2017 at 16:30 UTC ( #1200840=note: print w/replies, xml ) Need Help??


in reply to Re^2: Leaking Function Return
in thread Leaking Function Return

Just to explain one possibility of what might be going wrong in your original code without strict, so that it doesn't remain a mysterious "leak", because this kind of thing can theoretically bite you even under strict (although it's a lot less likely):

When you don't use strict, all the variables you use without a declaration are automatically "package variables", that is, they are global everywhere in their package, and since most scripts only have one package (the default, main), they're effectively global throughout the entire script. So anywhere you take a reference to an array that is a package variable (\@newArray), that's always going to refer to the same array (Update: I'm simplifying a bit and leaving out some "advanced" stuff like local for the sake of this explanation). So if you make modifications to that array anywhere in the script, they will be visible everywhere else. This may be what is biting you in your original code.

So when you do use strict, you're forced to declare all your variables e.g. with my or our. The latter actually declares package variables, so they'll have the same behavior as I just described. But variables declared with my are "private" to the enclosing block, meaning that code outside the block can't normally see or access them. Every time you call a subroutine that contains a my @newArray declaration, that will create a new memory location for you - this is the important part in this case. Every time you run that sub and do return \@newArray, that's a new array. (More details in Private Variables via my().)

Here's a demo, two functions that re-implement Perl's x operator for lists, one correctly and one incorrectly:

use warnings; use strict; use Data::Dump; sub good { my ($string,$times) = @_; my @array; # lexical variable push @array, $string for 1..$times; return \@array; } sub bad { my ($string,$times) = @_; our @array; # package variable # always the same "@array" here! push @array, $string for 1..$times; return \@array; } my $arr1 = good("foo",2); dd $arr1; # prints ["foo", "foo"] my $arr2 = good("bar",2); dd $arr2; # prints ["bar", "bar"] my $arr3 = bad("quz",2); dd $arr3; # prints ["quz", "quz"] my $arr4 = bad("baz",2); dd $arr4; # prints ["quz", "quz", "baz", "baz"]

Of course, it could also be something a bit simpler, like that you accidentally re-used variable names like @newArray or @arrayToBeManipulated in multiple places in your code.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1200840]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2018-01-23 18:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How did you see in the new year?










    Results (251 votes). Check out past polls.

    Notices?