Skip Menu |

This queue is for tickets about the Set-Scalar CPAN distribution.

Report information
The Basics
Id: 42449
Status: resolved
Priority: 0/
Queue: Set-Scalar

People
Owner: Nobody in particular
Requestors: jloverso [...] mathworks.com
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 1.22
Fixed in: (no value)



Subject: Set::Scalar objects lose '=' overloading
(This happens in Perl 5.8.8, and I've tested on MacOS 10.5.5, Linux, and Solaris). If two variables hold a reference to the same Set::Scalar object, then the '=' overload breaks. I suspect this might have something to do with the fact that the '+=' overload is inherited from Set::Scalar::Real. An example makes it clear: DB<1> use Set::Scalar DB<2> x $Set::Scalar::VERSION 0 1.22 DB<3> x $x = Set::Scalar->new(1..3) 0 Set::Scalar=HASH(0xcedb30) 'elements' => HASH(0xa5c960) 1 => 1 2 => 2 3 => 3 'universe' => Set::Scalar::Universe=HASH(0xc7b830) 'elements' => HASH(0xc87490) 1 => 1 2 => 2 3 => 3 'null' => Set::Scalar::Null=HASH(0xc7c200) 'universe' => Set::Scalar::Universe=HASH(0xc7b830) -> REUSED_ADDRESS 'universe' => undef DB<4> x $x += 4 0 Set::Scalar=HASH(0xcedb30) 'elements' => HASH(0xa5c960) 1 => 1 2 => 2 3 => 3 4 => 4 'universe' => Set::Scalar::Universe=HASH(0xc7b830) 'elements' => HASH(0xc87490) 1 => 1 2 => 2 3 => 3 4 => 4 'null' => Set::Scalar::Null=HASH(0xc7c200) 'universe' => Set::Scalar::Universe=HASH(0xc7b830) -> REUSED_ADDRESS 'universe' => undef DB<5> $y = $x DB<6> x $x += 5 Operation "=": no method found, argument in overloaded package Set::Scalar at (eval 16)[/mathworks/hub/share/apps/BuildTools/Linux/glibc-2.3.6/x86_64/perl/perl-5.8.8-tmw-026/lib/5.8.8/perl5db.pl:638] line 2. DB<7> x $x 0 Set::Scalar=HASH(0xcedb30) 'elements' => HASH(0xa5c960) 1 => 1 2 => 2 3 => 3 4 => 4 'universe' => Set::Scalar::Universe=HASH(0xc7b830) 'elements' => HASH(0xc87490) 1 => 1 2 => 2 3 => 3 4 => 4 'null' => Set::Scalar::Null=HASH(0xc7c200) 'universe' => Set::Scalar::Universe=HASH(0xc7b830) -> REUSED_ADDRESS 'universe' => undef DB<8> $y = 1 DB<9> x $x += 5 0 Set::Scalar=HASH(0xcedb30) 'elements' => HASH(0xa5c960) 1 => 1 2 => 2 3 => 3 4 => 4 5 => 5 'universe' => Set::Scalar::Universe=HASH(0xc7b830) 'elements' => HASH(0xc87490) 1 => 1 2 => 2 3 => 3 4 => 4 5 => 5 'null' => Set::Scalar::Null=HASH(0xc7c200) 'universe' => Set::Scalar::Universe=HASH(0xc7b830) -> REUSED_ADDRESS 'universe' => undef DB<10> Note that while '+=' breaks, '+' continues to work: DB<10> $y = $x DB<11> x $x += 6 Operation "=": no method found, argument in overloaded package Set::Scalar at (eval 22)[/mathworks/hub/share/apps/BuildTools/Linux/glibc-2.3.6/x86_64/perl/perl-5.8.8-tmw-026/lib/5.8.8/perl5db.pl:638] line 2. DB<12> x $x + 6 0 Set::Scalar=HASH(0xa5f630) 'elements' => HASH(0xcc44b0) 1 => 1 2 => 2 3 => 3 4 => 4 5 => 5 6 => 6 'null' => undef 'universe' => Set::Scalar::Universe=HASH(0xc7b830) 'elements' => HASH(0xc87490) 1 => 1 2 => 2 3 => 3 4 => 4 5 => 5 6 => 6 'null' => Set::Scalar::Null=HASH(0xc7c200) 'universe' => Set::Scalar::Universe=HASH(0xc7b830) -> REUSED_ADDRESS 'universe' => undef DB<13>
I didn't mean to change the status to 'open'. I thought that link would open another ticket. (blush)
From: jloverso [...] mathworks.com
This describes what causes this problem: http://www.perlmonks.org/?node_id=33772 And it's also described in the 'overload' pod in the sections 'Copy Constructor' and 'Metaphor clash' (but the above is much more straightforward). The answer as described above is to additionally provide an overload for '=' that does a clone operation. The intent is to make it work like this: $a += 1; $b = $a; # $b and $a point to same ref $a += 1; # clone $a and point to new ref, then invoke '+' overload. Unfortunately, this doesn't help my original problem, though. Where I came across this problem was in code that held several Set::Scalar objects inside another class. I had the logical equivalent of: sub getRunning {return shift->{running}} # same for getFinished and then I used this as: $running = $scoreboard->getRunning; $finished = $scoreboard->getFinished; ... $finished += $running; A 'clone' solution won't help me at all, because I want $finished to be the same object inside the '$scoreboard' object. My only recourse is to change the += to this, which doesn't read as nicely: $finished->insert($running->members);