hair-tearing perl question
What I want: a subroutine footle such that, if you call footle(a,b) twice with the same a,b, it does nothing the second time
What I did:
But this doesn't work because parameters are passed by value.
But if I call as footle("bootle","bumtrinket",\%isdone), which passes isdone by reference, it still does the footling twice.
Even if I put $_[2]=%done before the end of the subroutine, it still does the footling twice.
And if I put print join "*",(keys %done); at the start of the subroutine, it saysHASH(0x8188110)footling bootle bumtrinket
So how do I really pass the parameter by reference, as if I'd said void footle(int a, int b, set<string>& done) in C++?
What I did:
use strict;
sub footle
{
my ($a,$b,%done) = @_;
my $concat = $a.$b;
if ($done{$concat} == 0)
{
print "footling $a $b";
$done{$concat} = 1;
}
}
my %isdone = ();
footle("bootle","bumtrinket",%isdone);
footle("bootle","bumtrinket",%isdone);
But this doesn't work because parameters are passed by value.
But if I call as footle("bootle","bumtrinket",\%isdone), which passes isdone by reference, it still does the footling twice.
Even if I put $_[2]=%done before the end of the subroutine, it still does the footling twice.
And if I put print join "*",(keys %done); at the start of the subroutine, it says
So how do I really pass the parameter by reference, as if I'd said void footle(int a, int b, set<string>& done) in C++?
no subject
Completely untested:
sub footle
{
my ($a,$b,$done) = @_;
my $concat = $a.$b;
if (!exists $done->{$concat})
{
print "footling $a $b";
$done->{$concat} = 1;
}
}
my %isdone = ();
footle("bootle","bumtrinket",\%isdone);
footle("bootle","bumtrinket",\%isdone);
(no subject)
(no subject)
(no subject)
no subject
But there's something funny going on, because it *is* possible to pass a hash reference that you update, I've done it frequently I thought.
Maybe it's a syntax problem referring to the reference; I can't find an example where a hash reference is passed in, but when I dig one out of a structure in my working applications I see code like "if (keys(%{$picdb->{DBINFO}}))", that is, %{}.
Possibly using the right function template would help? (if only to make the calling sequence cleaner).
(no subject)
(no subject)
closure
Or you could use a closure and do away with the isdone:
{ my %c; sub foo { if ($c{$_[0]}{$_[1]}++) { print "$_[0] $_[1] already!\n"; return; } print "$_[0] $_[1]\n"; } sub clear { %c = () } # to reset the cache } foo("badger", "ferret"); foo("badger", "ferret");which also avoids the minor bug you had if suffixes of A and prefixes of B could get mixed up.
Re: closure
Re: closure