Acme::Bleach::Numerically - Fit the whole world between 0 and 1


Acme-Bleach-Numerically documentation Contained in the Acme-Bleach-Numerically distribution.

Index


Code Index:

NAME

Top

Acme::Bleach::Numerically - Fit the whole world between 0 and 1

SYNOPSIS

Top

  # 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";})

DESCRIPTION

Top

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!

EXPORT

This module autobleaches when no argument is passed via use. When you pass arguments, you can import str2num and num2str functions on demand.

BUGS

Top

This module is pretty slow when trying to bleach very large scripts.

SEE ALSO

Top

Georg Cantor http://en.wikipedia.org/wiki/Georg_Cantor

Acme::Bleach

Math::BigFloat

AUTHOR

Top

Dan Kogai, <dankogai@dan.co.jp>

COPYRIGHT AND LICENSE

Top

SIGNATURE

Top

  use Acme::Bleach::Numerically;
  0.43924578615781276573636996716277576435622482573471906469302823689043324274942438624694293330322859397882541185113124301737140129679390558528856757159461814533814416533092575624304971700174578115589069897446392714317394330698719965791863652492717345302658253407691232285183052024315270516691972601467999332334238068845967684072917336379759944975376129150390625


Acme-Bleach-Numerically documentation Contained in the Acme-Bleach-Numerically distribution.

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!