Memoization 0 - PHP 1

Tuesday, 24 October 06
Avevo trovato un modo molto piu' elegante di rendere una funzione memoized. In pratica basta aggiungere a qualunque funzione PHP, all'inzio, il seguente codice, e la funzione diventa magicamente con la cache, anche se con qualche limitazione (non puo' prendere Array come parametri):
    $__self = 'nomefunzione';
    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.';');
    }
(vediamo chi capisce come funziona...)

Si noti che nella prima riga la variabile __self deve essere settata al nome della funzione che stiamo rendendo memoized.

Un tale approccio per essere comodo necessita pero' l'inserimento di questo codice dentro un file memo.php, a questo punto per rendere la funzione memoized basterebbe aggiungere due righe alla funzione ed e' fatta:
function foobar(...) {
    $__self='foobar';
    include("memo.php");

    ... tutto il resto del codice ...
}
E invece no!... ti pareva troppo facile che PHP ne lasciasse passare una, eh.. perche' include() non e' privo di quelle grandi magie che contraddistinguono il nostro linguaggio spreferito, infatti return ha un valore particolare negli include, il suo effetto e' quello di terminare la inclusione e ritornare un valore (che verra' ritornato dalla chiamata include() stessa).

Risultato: non potete includere in una funzione del codice che contiene return come se lo aveste digitato direttamente dentro la funzione.

Peccato perche' l'idea di base del trucco mi piaceva...

2794 views*
Posted at 07:30:00 | permalink | discuss | print