Side effects of overloading quotes ""

Side effects of overloading quotes ""

am 28.11.2007 21:07:06 von koszalekopalek

Hello,

I overloaded the quotes '""' in my class by using
use overload ('""' => \&getDesc);

I was hoping it will allow me to write
print ("Hello from object $obj.\n");
instead of
print ("Hello from object " . $obj->getDesc() . ".\n");

Well, it works that way but there are side effects that break my class
completely.


Problem 1)

Before overloading, statement
if ($obj)
is true, if $obj is a reference to any object of class Obj.
If the reference is undef, $obj is false.
After overloading "", $obj is also false if getDesc() happens to
return an empty string! That's not what I wanted. If I did, I could
use
if ("$obj")


Problem 2)

Before overloading I could compare object references
if ($obj1 == $obj2)
and check if they point to the same location/object. I can no
longer do that once the '""' operator has been overloaded.

Operation "==": no method found,
left argument in overloaded package Obj,
right argument in overloaded package Obj at ./a.pl
line 38.

I can use eq instead of == if I also add falllback => 1 to the
overload pragma but that string-compares $obj1->dummy()
with $obj2->dummy() instead of object references. Again, if
I wanted to compare the string representation I could do
if ("$obj1" eq "$obj2")

Am I doing sth wrong or miss the point completely? Or is this
overload module broken?

I enclose a short listing that demonstrates my point.
Uncomment one of the #use clauses to see how it breaks(?)
things. Any help will be appreciated.

#!/usr/bin/perl
use strict;
use warnings;

{
package Obj;
#use overload ('""' => \&getDesc);
#use overload ('""' => \&getDesc, fallback => 1);

sub new ()
{
my $class = shift;
my $self = {};

bless $self, $class;

}

sub getDesc ()
{
return "";

};
};

my $obj1 = Obj->new();
my $obj2 = Obj->new();

### PROBLEM 1 ###
if ($obj1) {
print "true\n";
} else {

print "false\n";

};

### PROBLEM 2 ###
if ($obj1 == $obj2) {
print "same references\n";
} else {

print "different references\n";

};

__END__


I originally posted it to comp. lang perl. misc but maybe *.modules
is better suited for this.

Koszalek

Re: Side effects of overloading quotes ""

am 28.11.2007 21:45:04 von Claudio Calvelli

On 2007-11-28, Koszalek Opalek wrote:
> Problem 1)
>
> Before overloading, statement
> if ($obj)
> is true, if $obj is a reference to any object of class Obj.
> If the reference is undef, $obj is false.
> After overloading "", $obj is also false if getDesc() happens to
> return an empty string! That's not what I wanted. If I did, I could
> use
> if ("$obj")

This is the documented behaviour:
"String, numeric, and boolean conversion are calculated in terms of one
another if not all of them are defined."

In this case, it tries to convert your object to a Boolean, and since you
don't have a method for that, it converts it to string and tests the
string. You can fix that by adding a conversion for Boolean - in this
case, you want any object to be considered true, so the following will do:

use overload bool => sub { 1 };

> Problem 2)
>
> Before overloading I could compare object references
> if ($obj1 == $obj2)
> and check if they point to the same location/object. I can no
> longer do that once the '""' operator has been overloaded.
>
> Operation "==": no method found,
> left argument in overloaded package Obj,
> right argument in overloaded package Obj at ./a.pl
> line 38.

You have the problem of extracting something unique about the
reference so you can compare it. Maybe you could have something
like (yes I know it's not pretty; but then I am an INTERCAL programmer):

use overload "==" => \&compare;
.....
sub new ()
{
my $class = shift;
my $self = {};
$self->{unique} = "$self";
bless $self, $class
}
....

sub compare {
my ($a, $b) = @_;
$a->{unique} eq $b->{unique};
}


Note that the conversion of $self to a string must be before you bless it.

C

--
The address in the "From" header won't work. Email to "usenet" at "intercal" dot
"dyn-o-saur" dot "com" may or may not reach me, depending on how far it manages
to go through the spam filter, and other conditions which I won't disclose.