develooper Front page | perl.perl5.porters | Postings from October 2003

Re: Data::Dumper, BigInt, GMP and Dumper()

Thread Previous
October 13, 2003 10:20
Re: Data::Dumper, BigInt, GMP and Dumper()
Message ID:

Moin Orton,

thanx for the answer. Below is my reply:

On Monday 13 October 2003 11:54, you wrote:
> > v5.8.1 does Dump Math::BigInt variables wrong when their
> > internal data typ is
> > a Math::BigInt::GMP:
> >
> > 	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
> > 	Math::BigInt->new(123); print Dumper( $a )'
> > 	$VAR1 = bless( {
> >                  'sign' => '+',
> >                  'value' => bless( do{\(my $o = 137245040)},
> > 		'Math::BigInt::GMP' )
> >                }, 'Math::BigInt' );
> Could you tell me what this _should_ look like please? I am working a new
> dumper to resolve certain problems in Data::Dumper (Its mostly complete
> now) and I will endeavour to ensure that Math::BigInt objects are dumped
> correctly.

I have to think about this. Now, the easiest way (to write it) would be:

	'value' => 'Math::BigInt::GMP->_new(\"123")',

But I guess this is not possible for Data::Dumper to find out.

> > Is there any way to specifiy how an object (c/sh)ould be
> > dumped? Like adding a
> > DUMPME routine that returns the string for Dumper()? Hm, the doc says
> > Data::Dumper::Freezer might be usefull. Let's try it:
> >
> > 	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
> > 	Math::BigInt->new('12345678901234567890');
> > $Data::Dumper::Freezer = 'bstr';
> > 	print Dumper( $a )
> > 	Segmentation fault
> >
> > Oops. Maybe it wants a coderef despite the doc claiming otherwise?
> No it doesnt want a coderef. Freezer is a subroutine that needs to change
> the INTERNAL state of the object. 'bstr' if I understand correctly returns
> a string. This is not the same thing as collapsing the internals of the
> object into a format that can be dumped.
> Think of it this way. Freezer tells the object to pack itself up into a
> portable format. Toaster tells the object that it is in a portable format
> and that it should now unpack itself into a real object for use.
> So given what ive seen of the dump above you might want something like
> this:
> sub Math::BigInt::Freezer {
>   my $self=shift;
>   my $bstr=$self->bstr();
>   %$self=(FROZEN=>$bstr);
> }
> sub Math::BigInt::Toaster {
>   my $self=shift;
>   # ...  contents left as an excercise for the student :-) ...
> }
> So now you would say
> $Data::Dumper::Freezer="Freezer";
> $Data::Dumper::Toaster="Toaster";
> And things should work

Yes, but the problem is that the doc does nowhere specify this and I couldn't 
find it out by trial and error or *gasp* delving in the code :)

In any event, I think if you are building a new dumper, that would be cool. 
Especially if you could think of or (get?) reserve names that can be 
specified on a per-class basis like FREEZME or THAWME. I think Data::Storable 
has something like this. Actually, for Dumper you need only one, like DUMPE.

Each class could than provide a method that returns a hash, array or string 
that can be dumped. Chaning the internal state of the object might _not_work, 
because that would surely destroy the object in the process...which might 
cause all sorts of failures later on..

> > No. Maybe let's try 'print'. Just for kickers:
> >
> > 	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
> > 	Math::BigInt->new('12345678901234567890');
> > $Data::Dumper::Freezer = 'print';
> > 	print Dumper( $a )'
> > 	WARNING(Freezer method call failed): Can't locate
> > object method "1" via
> I find this interesting. I dont see why it happened like that at all. It
> should say cant find method 'print' via Math::BigInt...
> BTW, the perl code for freezing in DD is really simple:
>     if (my $freezer = $s->{freezer}) {
>       $val->$freezer() if UNIVERSAL::can($val, $freezer);
>     }
> The weird bugreports youve recieved are beyond me as I dont understand the
> DD XS code that well. Try using the latest DD and set
> $Data::Dumper::Useperl=1 to force it to use the perl code only. (This also
> relieves some memory leaks encountered in the XS code on Win32.)

I am under Linux :) I have:

	# perl -MData::Dumper -le 'print $Data::Dumper::VERSION'

First, my example above had some quotation issues with the shell, but 
reversing them also leads to a segfault. However, the pureperl version does 
not segfault:

 	# perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
	Math::BigInt->new("12345678901234567890"); $Data::Dumper::Freezer = "bstr";
	print Dumper($a)'
	Segmentation fault
	# perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
	Math::BigInt->new("12345678901234567890"); $Data::Dumper::Useperl=1; 
	$Data::Dumper::Freezer = "bstr"; print Dumper($a)'
	$VAR1 = bless( {
                 'sign' => '+',
                 'value' => bless( do{\(my $o = 137303504)},
	 'Math::BigInt::GMP' )
              }, 'Math::BigInt' );

> So, what you _might_ want to do is define a freezer/toaster method for
> Math::BigInt in general.

If you add support f.i. for DUMPE(), then I would certainly be happy to add 

> This would be useful becuase _my_ dumper (Data::BFDump v0.6, not the
> version on CPAN), handles per class Freezer methods (instead of DD's one
> per all classes being dumped), and given that Math::BigInt is part of core
> I would have no problem preseeding the table with the appropriate methods.

I didn't quite understand your last comment. However, I realize that I 
probably need to add something to Math::BigInt::GMP (BigInt alone works 
fine), but I am not sure what.

For your information, Math::BigInt::GMP does this in XS:

# _new()

mpz_t *
        SV*     class
        SV*     x
    SV* s;

    s = (SV*)SvRV(x);                   /* ref to string, don't check ref */
    RETVAL = malloc (sizeof(mpz_t));
    mpz_init_set_str(*RETVAL, SvPV_nolen(s), 0);

(I am not even sure if this is "proper" XS - my XS is basically Cute&Paste 
spiced up with trial-and-error :-)

Thank you for your time!


- -- 
 Signed on Mon Oct 13 19:03:48 2003 with key 0x93B84C15.
 Visit my photo gallery at
 PGP key on or per email.

 "Now, _you_ behave!"

Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)
Comment: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.


Thread Previous Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About