Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Operator overloading/Inheritance from built-in types?

10 views
Skip to first unread message

Wim Vanderbauwhede

unread,
Oct 5, 2006, 10:07:56 AM10/5/06
to perl6...@perl.org
Hi all,

I want to create a kind of bitvector object. Ideally, I'd like to inherit
from Array and then overload [],=, +,- etc.
I tried to overload the '+' operator, but I can't get it to work as a
method. Also, I'd like to overload the assignment operator.
Is that at all possible?
Below is my attempt, with the ideal solution and the received errors in
comments.

Any suggestions?

Thanks,

Wim

------
use v6;

my $vec=Register.new(dec=>7);
# my $vec=Register.new(7);
# or even better:
# my Register $vec=7;

say $vec.reg;
# say vec[]; # undefined!
# new() should calculate reg. But how?

say $vec.dec;
# say $vec;

$vec.write(29);
# $vec=29;

say $vec.read(2,4);
# say $vec[2..4]

say $vec.read(3);
# say $vec[3]

say $vec.add(5);
# say $vec+=5; # *** Cannot cast from VObject (MkObject {objType = (mkType
"Register") ... to Double (VNum)

# say $vec + 5; # *** No compatible subroutine found: "&dec"

#----
class Register {
has $.reg;
has $.dec;

method write ($self: $n) {
$self.dec= $n;
$self.reg= int2vec($n);
}

method read ($self: $i,$j=$i) {
return $self.reg[$i..$j];
}

method add ($n) {
$.dec+=$n;
$.reg = int2vec($.dec)
}

# This doesn't work: *** Missing invocant parameters in '&infix:+': 0
received, 1 missing
# method infix:<+> ($self: Int $n) {
# $self.add($n);
# }

sub int2vec ($n,$v=[]) {
if ($n > 1) {
if ($n % 2) {
int2vec(($n-1)/2,[1,@$v]);
} else {
int2vec($n/2,[0,@$v]);
}
} else {
return [$n,@$v];
}
}
}

#sub infix:<+> (Register $self, Int $n) {
# return $n+$self.dec;
#}

#sub infix:<+=> (Register $self, Int $n) {
# $self.add($n);
#}

--
If it's pointless, what's the point?
If there is a point to it, what's the point?
(Tibor Fischer, "The Thought Gang")

David Brunton

unread,
Oct 5, 2006, 4:01:34 PM10/5/06
to perl6...@perl.org
Hopefully the following will help. If I've missed the thrust of your
questions, feel free to disregard while someone else improves on my
answer :) I only overloaded the infix:<+> operator, but it should give
you an idea.

I would write the class comme ça:

use v6-alpha;

class Register {
has @.reg; # since it's list-ish anyhow
has $.dec;

submethod BUILD (:$.dec) {
@.reg = int2vec( $.dec ); # new() calculates reg
}

multi sub *infix:<+> (Register $self, Int $n) {
return $self.dec + $n;
}

sub int2vec ($n) {
+<<(sprintf("%b",7).split('')); # now I'm just golfing :-D
}
}

my Register $vec .= new(:dec(7));
say $vec.reg;
say $vec.dec;
say $vec + 2;

I don't think I get much extra credit, but this should give you the
infix operator and the new() behavior you're looking for.

Also, your int2vec is faster. I just wanted to use sprintf("%b",7) so
I could mention again how I wrote it.

hee hee.

-db.


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

David Brunton

unread,
Oct 5, 2006, 4:09:51 PM10/5/06
to David Brunton, perl6...@perl.org
Haha, that will teach me for trying to golf on public mailing lists.

It should actually read:

sub int2vec ($n) {
+<<(sprintf("%b",$n).split('')); # now I'm just golfing :-D
}

unless you only ever want to use it with the number 7.

-db.

0 new messages