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...