Overloading

B

Ben Morrow

I've been playing with overloading, and the following is puzzling
me... the script

#!/usr/bin/perl -l

use warnings;
use strict;

{{

package I;

use overload
"0+" => sub {
my $s = shift;
my $v = $$s;
print "numify";
0+$v;
},
q{""} => sub {
my $s = shift;
my $v = $$s;
print "stringify";
"$v";
},
"=" => sub {
my $s = shift;
my $v = $$s;
print "copy";
my $t = $v;
bless \$t;
},
"-" => sub {
my $s = shift;
my $v = $$s;
my $a = shift;
print "sub($a)";
$$s = (shift) ? $v - $a : $a - $v;
};

sub new {
my $c = shift;
my $s = shift;
bless \$s, $c;
}

}}

my $i = new I "*";
print $i;
print int($i);
print $i--;

__END__

prints

stringify
*
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
0
sub(1)
Argument "*" isn't numeric in subtraction (-) at ./op line 35.
stringify
1

about which I have two questions:

1. Why is 'numify' called twice for int($i)?

2. Why is 'numify' not called at all before calling '-'? OK, I guess
that makes sense... but why, then, will '-' not autogenerate in
terms of 'numify'? Is there any way to call it, without giving the
sub a name (i.e., is it possible to simply 'numify' a scalar, as
"$s" will stringify)?

Ben
 
J

Jim Keenan

Ben Morrow said:
I've been playing with overloading, and the following is puzzling
me... the script
[snip]

prints

stringify
*
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
0
sub(1)
Argument "*" isn't numeric in subtraction (-) at ./op line 35.
stringify
1

about which I have two questions:

1. Why is 'numify' called twice for int($i)?

2. Why is 'numify' not called at all before calling '-'? OK, I guess
that makes sense... but why, then, will '-' not autogenerate in
terms of 'numify'? Is there any way to call it, without giving the
sub a name (i.e., is it possible to simply 'numify' a scalar, as
"$s" will stringify)?

In attempting to reproduce your problem, I rearranged the code so as to put
package I at the top of the file, then explicitly called package main. I
also threw in some newlines for readability. The result: package main ran
without warnings.

package I;
use overload
"0+" => sub {
my $s = shift;
my $v = $$s;
print "numify";
0+$v;
},

q{""} => sub {
my $s = shift;
my $v = $$s;
print "stringify";
"$v";
},

"=" => sub {
my $s = shift;
my $v = $$s;
print "copy";
my $t = $v;
bless \$t;
},

"-" => sub {
my $s = shift;
my $v = $$s;
my $a = shift;
print "sub($a)";
$$s = (shift) ? $v - $a : $a - $v;
};

sub new {
my $c = shift;
my $s = shift;
bless \$s, $c;
}

1;

package main;
use warnings;
use strict;

my $i = new I "*";
print $i, "\n";
print int($i), "\n";
print $i--, "\n";

__END__
# above code prints:

stringify*
numify0
sub(1)stringify1
 
B

Ben Morrow

Jim Keenan said:
In attempting to reproduce your problem, I rearranged the code so as to put
package I at the top of the file,
Why?

then explicitly called package main.

package is lexical, so the braces make sure we go back to main::.
I also threw in some newlines for readability.

....which is why I used '#!/usr/bin/perl -l', which puts in all those
newlines and several more.
The result: package main ran without warnings.

....because you didn't turn them on early enough. Well done.

Ben
 
J

Jim Keenan

Ben Morrow said:
I find it makes the code more readable in cases where I'm including >1
package in a file rather than pulling one in via 'use'. I developed this
practice while working thru code examples in Damian Conway's "Object
Oriented Perl."
package is lexical, so the braces make sure we go back to main::.


...which is why I used '#!/usr/bin/perl -l', which puts in all those
newlines and several more.
Okay.


...because you didn't turn them on early enough.

Okay ... so then I went back to your original posting and copied-and-pasted
your code exactly as you typed it. When I ran it, I was unable to reproduce
the first of the two problems you cited:
1. Why is 'numify' called twice for int($i)?
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
numify
Argument "*" isn't numeric in addition (+) at ./op line 15.
0

I did not get the first 2 lines -- only the last 3.



and Well done.
Ben

--
If you put all the prophets, | You'd have so much more reason
Mystics and saints | Than ever was born
In one room together, | Out of all of the conflicts of time.
(e-mail address removed) |----------------+---------------| The Levellers,
'Believers'
 
B

Ben Morrow

Jim Keenan said:
Okay ... so then I went back to your original posting and copied-and-pasted
your code exactly as you typed it. When I ran it, I was unable to reproduce
the first of the two problems you cited:

They're not exactly 'problems', more things I am curious to know the
reason for..
I did not get the first 2 lines -- only the last 3.

Interesting. Which version of perl is this? I'm using 5.8.2.

Ben
 
J

James E Keenan

Ben Morrow said:
Interesting. Which version of perl is this? I'm using 5.8.2.
Ah, the plot thickens! The version on which I first tested both your
original script and my re-ordering it was 5.6.1. Today I'm working
with 5.8.0; testing *both* scripts reproduces your original finding:
the doubling of the 'numify' printout and the subsequent warning.
Implication: This was something that changed between 5.6.1 and 5.8.0.

Perhaps we should turn this over to p5p!

Jim Keenan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top