Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Math::BigInt new

by QM (Parson)
on Sep 27, 2012 at 15:25 UTC ( #996030=perlquestion: print w/replies, xml ) Need Help??
QM has asked for the wisdom of the Perl Monks concerning the following question:

Math::BigInt new does something funny when creating a new object from an existing Math::BigInt object:
#!perl use strict; use warnings; use Math::BigInt; my $x = new Math::BigInt 27; my $y = $x->new(44); # this is the funny bit my $z = Math::BigInt->new(99); exit;

From the debugger, this is what $y is:
DB<1> x $y 0 27=HASH(0x14f15ac) 'sign' => '+' 'value' => ARRAY(0xbc9cd4) 0 44

Why is the class now '27'? And a print on $y gives:
DB<2> p $y 27=HASH(0x14f15ac)

While the 'value' is right, any further operations with $y are wrong.

Update: Bug reported here.

Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re: Math::BigInt new
by tobyink (Abbot) on Sep 27, 2012 at 15:30 UTC

    $x overloads stringification, stringifying as "27". The new method presumably does something like:

    sub new { my ($class, $value) = @_; bless { value => $value } => "$class"; }

    Thus you end up with a reference blessed into package "27".

    Generally speaking, constructors are designed to be called as class methods not object methods.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Agreed. However, here is the first part of new:
      sub new { # create a new BigInt object from a string or another BigInt object. + # see hash keys documented at top # the argument could be an object, so avoid ||, && etc on it, this w +ould # cause costly overloaded code to be called. The only allowed ops ar +e # ref() and defined. my ($class,$wanted,$a,$p,$r) = @_; # avoid numify-calls by not using || on $wanted! return $class->bzero($a,$p) if !defined $wanted; # default to 0 return $class->copy($wanted,$a,$p,$r) if ref($wanted) && $wanted->isa($class); # MBI or subclass $class->import() if $IMPORT == 0; # make require work my $self = bless {}, $class;
      If it gets to the last line, and $class == 27, then $class must have been changed somewhere?

      And generally speaking, if I want a new object from an existing object, shouldn't the existing object be able to create one for me? Or do I have to go around doing this?

      my $y = {ref $x}->new();

      (or whatever the syntax is for that)

      Quantum Mechanics: The dreams stuff is made of

        $class is the same as $x (i.e. the bigint 27) the whole way through new, and bless implicitly stringifies its second argument (like print implicitly stringifies its arguments).

        ref($x)->new(48) should do what you want. Another reasonably common idiom is:

        my $new = (ref($existing) // $existing)->new(...)

        This allows $existing to be either an existing object or a class name.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        I also think this is strange. There is no checking for ref($class). I guess something like ...

        if ( ref($class) ){ my $t = $wanted; $t =~ s/^[+-]//; return bless { sign => $class->{sign}, value => $CALC->_new($t), }, ref($class); }
        should be in new constructor, doesn't it?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://996030]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2018-04-23 22:18 GMT
Find Nodes?
    Voting Booth?