You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following code unexpectedly invokes the tied FETCH function twice on every iteration line. If instead the code returned a non-overloaded object then this only happens once.
use v5.14;
use warnings;
package BoldStars {
use overload
'""' => sub {
my $self = shift; ## <-- THIS is line 7
my $str = $self->[0];
# Wrap every word in *stars*
return $str =~ s/(\S+)/*$1*/gr;
},
fallback => 1;
sub new {
my $class = shift;
my $self = bless [ $_[0] ], $class;
return $self;
}
}
package TiedCounter {
use Carp;
my $dashes = "";
sub TIESCALAR {
my $class = shift;
return bless [], $class;
}
sub FETCH {
carp "FETCHing TiedCounter";
$dashes .= "-";
return BoldStars->new( $dashes );
}
}
tie my $tiecounter, "TiedCounter";
say $tiecounter for 1 .. 5; ## <-- THIS is line 37
I'd expect it to print 5 rows of output with each one having one more dash than the prior:
*-*
*--*
*---*
*----*
*-----*
but instead it prints:
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
FETCHing TiedCounter at tie-fetch-twice.pl line 7.
*--*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
FETCHing TiedCounter at tie-fetch-twice.pl line 7.
*----*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
FETCHing TiedCounter at tie-fetch-twice.pl line 7.
*------*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
FETCHing TiedCounter at tie-fetch-twice.pl line 7.
*--------*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
FETCHing TiedCounter at tie-fetch-twice.pl line 7.
*----------*
The FETCH function really was run twice for each call. Each row has two more dashes than the prior. The FETCH call from line 37 was expected, the one from lines 7 was most certainly not.
If you remove the use overload ... declaration then this goes away and only runs once (and overloading no longer happens of course):
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
BoldStars=ARRAY(0x556a4784bf70)
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
BoldStars=ARRAY(0x556a4784b4d8)
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
BoldStars=ARRAY(0x556a4784c210)
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
BoldStars=ARRAY(0x556a47858a78)
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
BoldStars=ARRAY(0x556a4781e8c0)
The text was updated successfully, but these errors were encountered:
I dug into this, and have prepared a patch. (breaking on pp_study in gdb helps debugging this.)
Basically the same call to sv_2pv_flags() would trigger the mg_get() from about 5 lines apart. The problem (i think) is that the tied result of the first getmagic is called directly, instead of via a copy of the RV. See #20574.
$ ./perl tie-fetch-twice.pl
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
*-*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
*--*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
*---*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
*----*
FETCHing TiedCounter at tie-fetch-twice.pl line 37.
*-----*
The following code unexpectedly invokes the tied
FETCHfunction twice on every iteration line. If instead the code returned a non-overloaded object then this only happens once.I'd expect it to print 5 rows of output with each one having one more dash than the prior:
but instead it prints:
The
FETCHfunction really was run twice for each call. Each row has two more dashes than the prior. TheFETCHcall from line 37 was expected, the one from lines 7 was most certainly not.If you remove the
use overload ...declaration then this goes away and only runs once (and overloading no longer happens of course):The text was updated successfully, but these errors were encountered: