Quasi una macro in PHP

Thursday, 26 October 06
Poco fa ho riprovato a trovare un modo piu' semplice per creare funzioni memoized in PHP senza troppi sforzi da parte del programmatore. Sono riuscito ad ottenere una funzione che genera funzioni memoized che somiglia lontanamente ad una macro, ecco qui il codice, con il solito esempio di Fibonacci:

function memofunction($name,$arglist,$body) {
    $prefix = "
    \$__self = '__FUNCNAME__';
    global \$__memo;
    global \$__flag;
    if (!isset(\$__memo)) {
        \$__memo = Array();
        \$__flag = Array();
    }
    \$__argv = func_get_args();
    \$__argc = count(\$__argv);
    \$__aux = '[\$__self]';
    \$__aux2 = '';
    for(\$__i = 0; \$__i < \$__argc; \$__i++) {
        \$__aux .= '[\$__argv['.\$__i.']]';
        \$__aux2 .= '\$__argv['.\$__i.'],';
    }
    \$__aux2 = trim(\$__aux2,',');
    \$__issetmemo = eval('return isset(\$__memo'.\$__aux.');');
    \$__issetflag = eval('return isset(\$__flag'.\$__aux.');');
    if (!\$__issetflag) {
        if (!\$__issetmemo) {
            eval('\$__flag'.\$__aux.'=true;');
            \$__retval = eval('return '.\$__self.'('.\$__aux2.');');
            eval('unset(\$__flag'.\$__aux.');');
            eval('\$__memo'.\$__aux.'=\$__retval;');
        }
        return eval('return \$__memo'.\$__aux.';');
    }"."\n";
    $body = str_replace("__FUNCNAME__",$name,$prefix).$body;
    eval('function '.$name.' ('.$arglist.') {'.$body.'}');
}

memofunction('fib','$n', ' if ($n <= 2) return 1; return fib($n-1)+fib($n-2); ');

echo(fib(30)."\n");


In pratica la funzione memofunction che accetta come parametri il nome della funzione, la lista di argomenti (separati da virgole se piu' di uno), e il corpo della funzione, crea una funzione a cui prepende il codice necessario per la memoization.

Credo sia piu' o meno il limite massimo di automatismo che il PHP riesca a dare da questo punto di vista.

Da notare la pesante carenza di un modo per definire stringhe che sia adatto a scrivere codice dentro. Infatti il corpo della funzione viene racchiuso tra ' ' nell'esempio, ma questo non permette di scrivere dentro dei caratteri ' non quotati.

Sarebbe stato molto piu' sensato se fuori dal contesto di while e altre strutture condizionali { e } potevano servire per la definizione di stringhe letterali contenenti qualunque cosa... ma purtroppo PHP e' cosi'. Tanto per capirci:
$a = {
   quello che ti pare ...
   bla bla "" ' ' ; yez!!
   $b = {};
};
Avrebbe dovuto assegnare a $a tutto quello che c'e' tra la prima { e la } chiusa corrispondente.

Ok dopo questo dichiaro chiusa la mia lotta contro i limiti del PHP dal punto di vista della memoization. Tra qualche giorno invece seguira' il secondo post della serie che tentera' di portare il PHP al limite dal punto di vista di qualche altra diversa funzionalita'.
2398 views*
Posted at 07:48:42 | permalink | discuss | print
Do you like this article?
Subscribe to the RSS feed of this blog or use the newsletter service in order to receive a notification every time there is something of new to read here.

Note: you'll not see this box again if you are a usual reader.

Comments

comments closed