Acme-Bleach-Numerically
view release on metacpan or search on metacpan
lib/Acme/Bleach/Numerically.pm view on Meta::CPAN
package Acme::Bleach::Numerically;
use 5.008001;
use strict;
use warnings;
our $VERSION = sprintf "%d.%02d", q$Revision: 0.4 $ =~ /(\d+)/g;
our $MAX_SIZE = 0x7fff_ffff;
use Math::BigInt lib => 'GMP'; # faster if there, fallbacks if not
use Math::BigFloat;
use Math::BigRat;
sub str2num{
my $str = shift;
return 0 if $str eq '';
Math::BigFloat->accuracy(length($str) * 8);
my $bnum = Math::BigFloat->new(0);
my $bden = Math::BigInt->new(256);
$bden **= length($str);
for my $ord (unpack "C*", $str){
$bnum = $bnum * 256 + $ord;
}
$bnum /= $bden;
$bnum =~ s/0+$//o;
return $bnum;
}
sub num2str{
my $num = shift;
return '' unless $num;
my $bnum = Math::BigFloat->new($num);
my $str = '';
while($bnum > 0){
$bnum *= 256;
my $ord = int $bnum->copy;
$str .= chr $ord;
$bnum -= $ord;
}
return $str;
}
sub import{
my $class = shift;
if (@_){ # behave nicely
my ($pkg, $filename, $line) = caller;
for my $arg (@_){
no strict 'refs';
next unless defined &{ "$arg" };
*{ $pkg . "::$arg" } = \&{ "$arg" };
}
}else{ # bleach!
open my $in, "<:raw", $0 or die "$0 : $!";
my $src = join '', grep !/use\s*Acme::Bleach::Numerically/, <$in>;
close $in;
# warn $src;
if ($src =~ /^0\.[0-9]+;?\s*$/){ # bleached
my $code = num2str($src);
eval $code;
}else{ # whiten
{
no warnings;
eval $src;
if ($@){ # dirty
$@ =~ s/\(eval \d+\)/$0/eg;
die $@;
}
}
open my $out, ">:raw", $0 or die "$0 : $!";
print $out
"use ", __PACKAGE__, ";\n",
str2num($src), "\n";
}
exit;
}
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
Acme::Bleach::Numerically - Fit the whole world between 0 and 1
=head1 SYNOPSIS
# To bleach your script numerically
use Acme::Bleach::Numerically;
print "Hello, world!\n";
# Or do your own bleaching
use Acme::Bleach::Numerically qw/num2str str2num/;
my $world = str2num(qq{print "hello, world!\n";})
=head1 DESCRIPTION
Georg Cantor has found that you can squeeze the whole world between
zero and one. Many say he went insane because of that but the reality
is, he just bleached himself with continuum hypothesis :)
This module does just that -- map your whole world onto a single point
between 0 and 1. Welcome to the Programming Continuum of Perl!
( run in 1.904 second using v1.01-cache-2.11-cpan-39bf76dae61 )