[bcn-pm] programilla Perl, inutil pero divertido
Jose Luis Perez Diez
jluis a escomposlinux.org
dic jul 15 02:02:50 PDT 2009
El Tuesday, 14 de July de 2009 17:34:46 Jordi Delgado va escriure:
> Buenas,
>
> Algunos os acordareis de aquel programilla en Lisp que os mostre en una
> reunion de mongers, que hacia memoizing auto-modificando su propio codigo.
> Bien, creo que esto no es posible en Perl, ya que se compila a bytecode y
> luego se interpreta (por cierto, si me equivoco y alguien sabe de una
> subrutina que, dado un nombre, retorne una string con el codigo fuente de
> la subrutina con ese nombre que lo diga; que yo sepa no existe).
http://search.cpan.org/~nwclark/perl-5.8.9/ext/B/B/Deparse.pm
http://search.cpan.org/~vpit/B-RecDeparse-0.04/lib/B/RecDeparse.pm
>....
> sub memoize_funny {
> my $code_string = 'if (1) { \'dummy\' };';
my $code_string = 'undef;';
> return sub {
> my $param = shift;
> my $result = eval $code_string;
> if ($result eq 'dummy') {
> $result = &costly($param);
> $code_string = "if (\$param == $param) { $result } els$code_string";
> } else {
> print "No costly call! Result: $result\n";
> }
if (defined $result ) {
print "No costly call! Result: $result\n";
} else {
$result = costly($param);
$code_string = "\$param == $param ?$result:$code_string";
}
>....
> Bueno, es para animar la lista, y si se os ocurre alguna manera mas bizarra
> de hacer lo mismo...
use B::Deparse;
sub costly {
return $_[0] + 1;
}
{
my $code_string = '';
sub memoize_funny {
my $param = shift;
print("Cheap\n") && return $1 if $code_string =~ /<$param>([^<]*)/;
my $result = costly($param);
$code_string .= "<$param>$result";
return $result;
}
}
while (<STDIN>) {
chomp;
die unless memoize_funny($_) == costly($_);
}
my $deparse= B::Deparse->new();
print $deparse->coderef2text(\&memoize_funny);
Més informació sobre la llista de correu Barcelona-pm