Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Overloading multiplication involving BigInt

by grondilu (Friar)
on Jan 13, 2012 at 15:40 UTC ( [id://947762]=perlquestion: print w/replies, xml ) Need Help??

grondilu has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I recently wanted to overload '*' with one of my class which can accept external multiplication with bigints.

In other words, I wanted to do something like:

my $obj = new My::Custom::Object; use bigint; my $mult = 2**100 * $obj;

I realised that overloading '*' inside My::Custom::Object would not be enough as the class resolution would first process '*' inside Math::BigInt if the number is the first operand.

So I thought I should directly overload '*' inside Math::BigInt. I guess I can do that even if this class is not "mine", right?

package Math::BigInt; use overload '*' => sub { if (ref $_[1] eq 'My::Custom::Object') { $_[1]->MultiplyByInt($_[0]); } else { $_[0]->bmult($_[1]); } }

I'm not sure this is a good solution, though. My concern is about using 'bmult' instead of '*'. I doubt bmult will behave correctly if something else than a BigInt is provided as a second operand.

I thought about creating a child class of Math::BigInt so '*' can fallback to parent '*' when necessary but then I'll have to explicitely bless my integers which would be annoying.

So, how should I do this right?

Replies are listed 'Best First'.
Re: Overloading multiplication involving BigInt
by pileofrogs (Priest) on Jan 13, 2012 at 21:43 UTC

    No one else is commenting, so I'll take a wild stab.

    Why not add more elsif branches to your sub? You say you're worried about bmul behaving badly if it's handed something other than a BigInt, so why not just check for it?

    You could also run some tests or read the source to find out what bmul really does if the 2nd operand isn't a BigInt.

    Why would you have to explicitly bless your integers if you made a subclass of Math::BigInt?

    And to step back a little: are you sure you want to do overloading? Will future users (or yourself) be flummoxed that $a*$b isn't doing what they expect? Is typing '$obj->mult($other_thing)' really that bad? At least that way you know exactly what you just did.

    Okay, that's about all I can think of. I hope I was helpful.

    --Pileofrogs

      Well, I had a look at Math::BigInt source code and it seemed to me that the '*' overloading had already a lot of elsif branches. I just don't want to reinvent the wheel and redo what has already been done. Basically I whish I could just say "if the second operand is a My::Custom::Object then do this, otherwise just do whatever '*' does in the Math::BigInt class".

      About explicit blessing, I just don't see how I could do it otherwise, unless I use a constructor anyway. But now that you make me think of it , I wonder if the magic of bigint wouldn't be inherited. I have to check this out, indeed.

      You are right about using overloading not being necessary. But it would definitely be cool.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://947762]
Approved by salva
Front-paged by salva
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-18 02:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found