I wanted to remove duplicate values from an array with this approach. The duplicates removal have to be executed inside a loop. Here is a minimal example that demonstrates the problem that I encountered:
use strict;
for (0..1){
my %seen;
sub testUnique{
return !$seen{shift}++;
}
my $res = testUnique(1);
if($res){
print "unique\n";
}else{
print "non-unique\n";
}
}
I define the %seen hash inside a loop, so I would expect it to be defined only during a single iteration of the loop.
The result of the above code is however:
unique
non-unique
With some debug prints, I found out that the value of %seen is preserved from one iteration to another.
I tried a trivial
for (0..1){
my %seen;
$seen{1}++;
print "$seen{1}\n";
}
And this one worked as expected. It printed:
1
1
So, I guess the problem is with inner function testUnique.
Can somebody explain me what is going on here?
Your testUnique sub closes over the first instance of %seen. Even though it is inside the for loop, the subroutine does not get compiled repeatedly.
Your code is compiled once, including the part that says initialize a lexically scoped variable %hash right at the top of the for loop.
The following will produce the output you want, but I am not sure I see are going down this path:
#!/usr/bin/env perl
use warnings;
use strict;
for (0..1){
my %seen;
my $tester = sub {
return !$seen{shift}++;
};
print $tester->(1) ? "unique\n" : "not unique\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With