develooper Front page | perl.perl5.porters | Postings from July 2008

[perl #57012] Result of FETCH not checked for overload?

From:
Bram via RT
Date:
July 27, 2008 11:30
Subject:
[perl #57012] Result of FETCH not checked for overload?
Message ID:
rt-3.6.HEAD-29762-1217098756-889.57012-15-0@perl.org
On Wed Jul 16 12:55:31 2008, sphink@gmail.com wrote:
> This is a bug report for perl from sphink@gmail.com,
> generated with the help of perlbug 1.35 running under perl v5.8.8.
> 
> 
> -----------------------------------------------------------------
> [Please enter your report here]
> 
> I have a tie'd variable %h that returns values from its FETCH()
> routine that are blessed into a package that uses overloads.
> When I use the += operator on the return value from that FETCH,
> the overloading is ignored.
> 
> If I use the + operator, it works fine.
> 
> Example (uncomment the two commented-out lines to prove that
> the overloading is ignored):
> 
> package Over;
> 
> use overload '+' => \&add;
> #use overload '+=' => \&add2;
> use overload '""' => \&toString;
> 
> sub add {
>   my ($a, $b, $swapped) = @_;
>   return bless [ $a->[0] + $b->[0], $a->[1] + $b->[1] ], 'Over';
> }
> 
> #sub add2 { die "add2 called" }
> 
> sub toString {
>   my ($self) = @_;
>   return "<$self->[0],$self->[1]>";
> }
> 
> package Tied;
> 
> sub TIEHASH {
>   my ($selfpkg, $data) = @_;
>   return bless \$data, $selfpkg;
> }
> 
> sub FETCH {
>   my ($self, $key) = @_;
>   return bless [ $key, $key ], 'Over';
> }
> 
> sub STORE {
>   my ($self, $key, $value) = @_;
>   print "STORE($key,$value) called\n";
> }
> 
> package main;
> 
> my $v = bless [ 1, 2 ], 'Over';
> 
> my %h;
> tie %h, 'Tied';
> 
> print "v = $v\n";
> print "h{1} = $h{1}\n";
> print "h{1} + [10,10] = ", ($h{1} + [10,10]), "\n";
> print "h{1} += [10,10] = ", ($h{1} += [10,10]), "\n";
> # The overloading was ignored on the previous line. It correctly
> # fetched key '1' and converted it into a blessed ref, but then
> # when it applied the += operator to the result, it didn't respect
> # the overloading.
> 
> [Please do not change anything below this line]
> -----------------------------------------------------------------
> ---

Same behaviour in perl-blead.
Note that this also applies to tied arrays.

Minimal test cases:

Normal array:
#!/usr/bin/perl -l

use strict;
use warnings;

use overload '+=' => sub { die "Overloaded +="; };

my @h;
$h[0] = bless {}, "main";
$h[0] += 12;
__END__
Overloaded += at rt-57012.pl line 6. (expected)

Tied array:
#!/usr/bin/perl -l

use strict;
use warnings;

use Tie::Array;
use overload '+=' => sub { die "Overloaded +="; };

my @h;
tie @h, "Tie::StdArray";
$h[0] = bless {}, "main";
$h[0] += 12;
__END__
Operation "0+": no method found, argument in overloaded package main at 
rt-57012.pl line 12. (not expected)


Normal hash:
#!/usr/bin/perl -l

use strict;
use warnings;

use overload '+=' => sub { die "Overloaded +="; };

my %h;
$h{0} = bless {}, "main";
$h{0} += 12;
__END__
Overloaded += at rt-57012.pl line 6. (expected)
 

Tied hash:
#!/usr/bin/perl -l

use strict;
use warnings;

use Tie::Hash;
use overload '+=' => sub { die "Overloaded +="; };

my %h;
tie %h, "Tie::StdHash";
$h{0} = bless {}, "main";
$h{0} += 12;
__END__
Operation "0+": no method found, argument in overloaded package main at 
rt-57012.pl line 12. (not expected)



Behaviour of scalars:


Normal scalar:
#!/usr/bin/perl -l

use strict;
use warnings;

use overload '+=' => sub { die "Overloaded +="; };
             
my $h;       
$h = bless {}, "main";
$h += 12;
__END__
Overloaded += at rt-57012.pl line 6. (expected)


Tied scalar:
#!/usr/bin/perl -l

use strict;
use warnings;

use Tie::Scalar;
use overload '+=' => sub { die "Overloaded +="; },
             '=' => sub { return $_[0]; };

my $h;
tie $h, "Tie::StdScalar";
$h = bless {}, "main";
$h += 12;
__END__
Overloaded += at rt-57012.pl line 7.

(Note the copy constructor - no idea why it is needed.)






nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About