Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

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.

-QM
--
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)

      -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?
[erix]: then you might as well send that patch to the DBIC guys :)
[Corion]: erix: Yeah, I just found that it has no documentation at all on how to circumvent/ eliminate "1+n SELECTs" by building a local hash... I guess I have to make ->has_many do the hash lookup instead of doing the SQL query. But as the problem ...
[Corion]: ... has only manifested itself so far through the puzzled questions of other bystanders, I won't go deeper at this time. But the DBIx::Class documentation could well do with a document on how to make "it" (that is, ORMs in general) faster ;)
[Corion]: I find that DBIx::Class, like most ORMs makes things easy until they become performance critical and then makes it horribly hard to change things because the design is highly inflexible if you don't already know about the problems of 1+n :-/
[choroba]: that's why I don't like similar libraries. They pretend you don't have to learn SQL, but in the end, you have to learn how SQL plus to overcome their own limitations
[Corion]: "Just write the proper SQL beforehand" is of course the appropriate solution, but if you did that, you wouldn't/couldn't use DBIx::Class either. At least not in an obvious (to me) way.
choroba scratches a "how"
[Corion]: choroba: Exactly... But maybe that's just because I'm old and grumpy ;)

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2017-09-25 11:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (279 votes). Check out past polls.

    Notices?