Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Side effects of overloading quotes ""

Reply
Thread Tools

Side effects of overloading quotes ""

 
 
Koszalek Opalek
Guest
Posts: n/a
 
      11-28-2007
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
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 beyond repair?

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__

Koszalek
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      11-28-2007
Koszalek Opalek <(E-Mail Removed)> wrote in news:914a45bc-ea5a-
http://www.velocityreviews.com/forums/(E-Mail Removed):

> 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.


perldoc overload mentions:

* *Boolean, string and numeric conversion*
'bool', '""', '0+',

If one or two of these operations are not overloaded, the remaining
ones can be used instead. "bool" is used in the flow control
operators (like "while") and for the ternary "?:" operation. These
functions can return any arbitrary Perl value. If the corresponding
operation for this value is overloaded too, that operation will be
called again with this value.

As a special case if the overload returns the object itself then it
will be used directly. An overloaded conversion returning the
object is probably a bug, because you're likely to get something
that looks like "YourPackage=HASH(0x8172b34)".

> Problem 1)
>
> Before overloading
> 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")


Well, then, overload bool as well.

> 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.


Again, overload 0+.

> #!/usr/bin/perl
> use strict;
> use warnings;
>
>
> {
> package Obj;
> #use overload ('""' => \&getDesc);
> #use overload ('""' => \&getDesc, fallback => 1);


Don't comment out code in your posting. That makes it hard to figure out
exactly what code you ran.

> sub new ()


Don't specify prototypes for methods: They have no effect and their use
is misleading. All this time, I have not found a good reason to use
prototypes in my code.


> sub getDesc ()


Ditto for prototypes.

> {
> 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";
> };


The solution to Problem 1 is to implement boolean conversion. The
solution to Problem 2 is also found in perldoc overload:

Public functions
Package "overload.pm" provides the following public functions:

overload::StrVal(arg)
Gives string value of "arg" as in absence of stringify overloading.
If you are using this to get the address of a reference (useful for
checking if two references point to the same thing) then you may be
better off using "Scalar::Util::refaddr()", which is faster.


Thus, you should also implement the equality operator.

So, here is a reworked example. I did change method names to my liking:

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

package Obj;

use Scalar::Util qw( refaddr );

use overload
q{""} => \&to_string,
'bool' => \&to_bool,
q{0+} => \&to_val,
q{==} => \&is_identical,
;

sub new { bless {} => shift }

sub to_string { q{} }

sub to_bool { defined shift }

sub to_val { refaddr shift }

sub is_identical { refaddr shift == refaddr shift }

package main;

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

### PROBLEM 1 ###

print( $obj1 ? "true\n" : "false\n" );

### PROBLEM 2 ###

print( $obj1 == $obj2 ? "same\n" : "different\n" );

__END__




--
A. Sinan Unur <(E-Mail Removed)>
(remove .invalid and reverse each component for email address)
clpmisc guidelines: <URL:http://www.augustmail.com/~tadmc/clpmisc.shtml>

 
Reply With Quote
 
 
 
 
Koszalek Opalek
Guest
Posts: n/a
 
      11-29-2007
On Nov 28, 9:16 pm, "A. Sinan Unur" <(E-Mail Removed)> wrote:


> Don't comment out code in your posting. That makes it hard to figure out
> exactly what code you ran.


Ok.

> > sub new ()


> Don't specify prototypes for methods:


Sure.

> So, here is a reworked example. I did change method names to my liking:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> package Obj;
>
> use Scalar::Util qw( refaddr );
>
> use overload
> q{""} => \&to_string,
> 'bool' => \&to_bool,
> q{0+} => \&to_val,
> q{==} => \&is_identical,
> ;
>
> sub new { bless {} => shift }
>
> sub to_string { q{} }
>
> sub to_bool { defined shift }
>
> sub to_val { refaddr shift }
>
> sub is_identical { refaddr shift == refaddr shift }
>
> package main;
>
> my $obj1 = Obj->new;
> my $obj2 = Obj->new;
>
> ### PROBLEM 1 ###
>
> print( $obj1 ? "true\n" : "false\n" );
>
> ### PROBLEM 2 ###
>
> print( $obj1 == $obj2 ? "same\n" : "different\n" );
>
> __END__



Thank you.
That works beautifully.

A.


> --
> A. Sinan Unur <(E-Mail Removed)>
> (remove .invalid and reverse each component for email address)
> clpmisc guidelines: <URL:http://www.augustmail.com/~tadmc/clpmisc.shtml>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Asp.NET Javascript string, want to pass '(single quotes' within '(single quotes) Chris ASP .Net 1 03-24-2006 09:03 PM
Quotes/Double Quotes in Image Control Chris White ASP .Net 1 09-22-2004 06:22 AM
Anti-war quotes quiz and protest effects with JavaScript rgoya Javascript 15 05-20-2004 11:32 PM
Anti-war quotes quiz and protest effects with JavaScript rgoya HTML 7 05-20-2004 09:14 PM



Advertisments