Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Math::BigInt new

by QM (Vicar)
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.

-QM
--
Quantum Mechanics: The dreams stuff is made of

Comment on Math::BigInt new
Select or Download Code
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)

      -QM
      --
      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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://996030]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2015-07-03 17:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (55 votes), past polls