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
-
Data::Dumper, BigInt, GMP and Dumper()
by Tels