[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