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

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

Thread Next
From:
Tels
Date:
October 9, 2003 14:39
Subject:
Data::Dumper, BigInt, GMP and Dumper()
Message ID:
200310092340.44005@bloodgate.com
-----BEGIN PGP SIGNED MESSAGE-----

Moin,

Here is an easy way to create strange warnings and segfaults:

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' );

As seen here:

	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
	Math::BigInt->new('12345678901234567890'); print eval ( Dumper( $a ) )'
	12345678901234600000

A bit better than v.5.8.0, which produced a different string and then dumped 
core on the eval - but not much better :)

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?

	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
	Math::BigInt->new('12345678901234567890'); $Data::Dumper::Freezer = sub {
	print "hi"; }; print Dumper( $a )'
	$VAR1 = bless( {
                 'sign' => '+',
                 'value' => bless( do{\(my $o = 137300192)},
	 'Math::BigInt::GMP' )
               }, 'Math::BigInt' );

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
	package "Math::BigInt" at 
	/usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	WARNING(Freezer method call failed): Can't locate auto/Math/BigInt/GMP/1.al
	in @INC (@INC contains: /usr/local/lib/perl5/5.8.1/i686-linux 
	/usr/local/lib/perl5/5.8.1 /usr/local/lib/perl5/site_perl/5.8.1/i686-linux
	/usr/local/lib/perl5/site_perl/5.8.1 /usr/local/lib/perl5/site_perl .) at
	/usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158
	$VAR1 = bless( {
 	                'value' => bless( do{\(my $o = 137300672)}, 
		'Math::BigInt::GMP' ),
                 'sign' => '+'
               }, 'Math::BigInt' );
	Attempt to free unreferenced scalar.
	Attempt to free unreferenced scalar during global destruction.

Oouch. Another try:

	te@null:~> perl -MMath::BigInt=lib,GMP -MData::Dumper -le '$a =
	 Math::BigInt->new('12345678901234567890'); $Data::Dumper::Freezer = '_str'; 
	print Dumper( $a )'
	WARNING(Freezer method call failed): Can't locate object method "_str" via 
	package "Math::BigInt" at
	 /usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	WARNING(Freezer method call failed): Usage: Math::BigInt::GMP::_str(class, n)
	at /usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	$VAR1 = bless( {
                 'value' => bless( do{\(my $o = 137299344)},
	 'Math::BigInt::GMP' ),
                 'sign' => '+'
               }, 'Math::BigInt' );
	Attempt to free unreferenced scalar.
	Attempt to free unreferenced scalar during global destruction.

Ah, it is trying to call the method in Math::BigInt::GMP space. Cool. I could 
add one that returns "Math::BigInt::GMP->new('number');".. But why is it 
complaining that it cannot find the method in Math::BigInt, and then calls it 
from Math::BigInt::GMP? Does it try both of them? Any way to silence the 
first warning? Lets try to add _DUMPME to Math::BigInt::GMP:

	sub _DUMPME
 	 {
	  'Math::BigInt::GMP->new("' . ${_str('',$_[0])} . '");';
	 }

	te@null:~/perl/math/Math-BigInt-GMP-1.12> perl -Ilib -MMath::BigInt=lib,GMP
	-MData::Dumper -le '$a = Math::BigInt->new('12345678901234567890');
	$Data::Dumper::Freezer = '_DUMPME'; print Dumper( $a )'
	WARNING(Freezer method call failed): Can't locate object method "_DUMPME" via
	package "Math::BigInt" at
	/usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	cannot handle ref type 103 at
	/usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	$VAR1 = bless( {
                 'value' => ,
                 'sign' => '+'
               }, 'Math::BigInt' );
	Attempt to free unreferenced scalar.

Didn't know that there is a ref type 3.. Hm, no go. Let's try something 
simpler:

	sub _DUMPME
	 {
	  'Math::BigInt::GMP->new("1234");';
 	 }

I spare you the outout, same result. This one is better:

	sub _DUMPME
	 {
	  \'Math::BigInt::GMP->new("1234");';
 	 }

(note the reference). Now:

	te@null:~/perl/math/Math-BigInt-GMP-1.12> perl -Ilib -MMath::BigInt=lib,GMP
	-MData::Dumper -le '$a = Math::BigInt->new('12345678901234567890'); 
	$Data::Dumper::Freezer = '_DUMPME'; print Dumper( $a )'
	WARNING(Freezer method call failed): Can't locate object method "_DUMPME" via
	package "Math::BigInt" at 
	/usr/local/lib/perl5/5.8.1/i686-linux/Data/Dumper.pm line 158.
	$VAR1 = bless( {
                 'value' => \'Math::BigInt::GMP->new("1234");',
                 'sign' => '+'
               }, 'Math::BigInt' );
	Attempt to free unreferenced scalar.

Close, very close, but no cigar. Of course it is not possible to eval that 
back to a working object, at last not with very interesting segfaults...

I give up - it is bedtime, anyway :-)

Best wishes,

Tels

- -- 
 Signed on Thu Oct  9 23:16:19 2003 with key 0x93B84C15.
 Visit my photo gallery at http://bloodgate.com/photos/
 PGP key on http://bloodgate.com/tels.asc or per email.

 "Where shall I put you? Under H, like Hot, Sexy Mama?"

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

iQEVAwUBP4XV2ncLPEOTuEwVAQEOnAf8DvIXxzKQTXy1b3zdGYX6y2lFBFrCAwnf
3rMSblh7FKgsfM48ZBxXl/bPJoZXRSOhHXIBLjAaMFs3K3va8oo5hVNSMTcAYzGj
Gge9bfteZ6hNnb9Ywui6eQZI3+fQ7RyAQ12DZaoAMWlQsoYniXTj3VO2AljwNfXQ
vYoLuq12knkLNzASHRJX9C6tN+hol8vCKwpBrO1jQNI4yzB2AEgOFRf7BXNFTuoN
KItyOQ3h0HZB5GPbAOUOXfMhzyuo8XUzvInuWi9vadJ5+cPUfM2R56HZysncs5Aa
/jZu2zTU3zZrSkCeJzaroKMGj5mxB38NG9sKBBFwxeOsY6Yr2QF63Q==
=6Y1i
-----END PGP SIGNATURE-----


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About