3. Lambda Da “lambda calcolo” I nomi delle funzioni sono di pura “convenienza” e perciò tutte le funzioni sono considerate anonime A meno che si stia utilizzando un vero linguaggio di programmazione funzionale con funzioni di prima classe, generalmente si usano funzioni anonime o espressionilambda 3 Funzioni anonime in PHP 5.3
4. Closure (o chiusure) Una funzione che contiene un ambiente a riferimento Ciascuna funzione ha il suo scope Permette lo stato nascosto Un fattore di differenziazione è che le closure permettono i riferimenti collegati che esistono all’atto della creazione, da utilizzare quando sono chiamate 4 Funzioni anonime in PHP 5.3
5. Funzioni anonime Ciascuna funzione definita e/o chiamata senza essere collegata a un identificatore Si può assegnare la funzione a una variabile, ma non si dà il nome proprio 5 Funzioni anonime in PHP 5.3
7. Funtori Ciascun oggetto che definisce un metodo __invoke() Le istanze oggetto possono ora essere chiamate come se fossero funzioni class Command { public function __invoke($name) { echo "Ciao, $name"; } } $c = new Command(); $c(’Elena’); // "Ciao, Elena" 7 Funzioni anonime in PHP 5.3
8. Funzioni anonime Nuova classe Closure che definisce __invoke() Il corpo __invoke() è “sostituito” con la funzione definita Possibilità di collegare le variabili tramite importazioni, permettendo la creazione di closure 8 Funzioni anonime in PHP 5.3
9. Importante da sapere: Proprio come le normali funzioni PHP, le funzioni anonime esistono nel loro scope Non è possibile importare $this Non è possibile l’alias delle variabili importate 9 Funzioni anonime in PHP 5.3
11. Concetti di base Semplicemente, come una normale dichiarazione di funzione, tranne per fatto che non c’è il nome: function($value1[, $value2[, ... $valueN]]) { }; 11 Funzioni anonime in PHP 5.3
12. Assegnamento di variabile Assegnamento di funzioni a variabili; non dimenticare il punto e virgola alla fine ! $greet = function($name) { echo "Ciao, $name"; }; $greet(’Elena’); // "Ciao, Elena " 12 Funzioni anonime in PHP 5.3
13. Passaggio come argomento ad altri chiamabili Permette un’altra funzionalità per chiamare la funzione function say($value, $callback) { echo $callback($value); } say(’Elena’, function($name) { return "Ciao, $name"; }); // "Ciao, Elena" 13 Funzioni anonime in PHP 5.3
14. Creazione di closure Collegare le variabili alla creazione e usarle all’atto della chiamata $log = Zend_Log::factory($config); $logger = function() use($log) { $args = func_get_args(); $log->info(json_encode($args)); }; $logger(’foo’, ’bar’); // ["foo", "bar"] 14 Funzioni anonime in PHP 5.3
18. Scansione • La scansione permette di cambiare i valori di un array • Se non si utilizzano oggetti, allora è necessario passare per riferimento per poter modificare i valori $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’); array_walk($stuff, function(&$value) { $value = strtoupper($value); }); // ’APPLE’, ’ANISE’, ’APPLESAUCE’, ’APPLESEED’ 18 Funzioni anonime in PHP 5.3
19. Mappatura La mappatura esegue un lavoro su ciascun elemento dell’array, il risultato sarà un nuovo array che contiene i valori restituiti $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’); $mapped = array_map(function($value) { $value = strtoupper($value); return $value; }, $stuff); // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’) // $mapped: array(’APPLE’, ’ANISE’, ’APPLESAUCE’, ’APPLESEED’) 19 Funzioni anonime in PHP 5.3
20. Riduzione “Combina” gli elementi e restituisce un valore o un dataset Il valore restituito è passato come primo argomento della chiamata successiva Effettua il seeding sul valore restituito passando un terzo argomento ad array_reduce() $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’); $reduce = array_reduce($stuff, function($count, $input) { $count += substr_count($input, ’a’); return $count; }, 0); // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’) // $reduce: 3 20 Funzioni anonime in PHP 5.3
21. Filtraggio Restituisce solo gli elementi che sono riconosciuti come true Spesso questa è considerata una forma di mappatura ed è utilizzata per rifilare un dataste, solo su quegli elementi che sono di interesse primario per la riduzione $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’); $reduce = array_reduce($stuff, function($count, $input) { $count += substr_count($input, ’a’); return $count; }, 0); // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’) // $reduce: 3 21 Funzioni anonime in PHP 5.3
22. Operazioni su stringa Espressioni regolari (preg_replace_callback) Applicazione parziale (currying) degli argomenti 22 Funzioni anonime in PHP 5.3
23. preg_replace_callback() Permette di trasformare le corrispondenze estratte $string = "Today’s date next month is " . date(’Y-m-d’); $fixed = preg_replace_callback(’/({4}-{2}-{2})/’, function($matches) { $date = new DateTime($matches[1]); $date->add(new DateInterval(’P1M’)); return $date->format(’Y-m-d’); }, $string); // "Today’s date next month is 2011-05-26" 23 Funzioni anonime in PHP 5.3
24. Applicazione parziale (currying) degli argomenti In alcuni casi si possono fornire argomenti predefiniti: Per ridurre il numero di argomenti di cui si ha bisogno Per fornire valori ad argomenti opzionali Per fornire una signature unificata per le callback $hs = function ($value) { return htmlspecialchars($value, ENT_QUOTES, "UTF-8", false); }; $filtered = $hs("<span>Matthew Weier O’Phinney</span>"); // "<span>Matthew Weier O'Phinney</span>" 24 Funzioni anonime in PHP 5.3
26. Riferimenti Le variabili passate alle callback, come argomenti o come importazioni, non sono passate per riferimento Utilizzare oggetti, oppure Passare per riferimento $count = 0; $counter = function (&$value) use (&$count) { if (is_int($value)) { $count += $value; $value = 0; } }; $stuff = array(’foo’, 1, 3, ’bar’); array_walk($stuff, $counter); // $stuff: array(’foo’, 0, 0, ’bar’) // $count: 4 26 Funzioni anonime in PHP 5.3
27. La combinazione con altri chiamabili Problemi e considerazioni: Closure è un “dettaglio di implementazione”; il typehinting (suggerimento di tipo) esclude gli altri tipi callback is_callable()dice solo che può essere chiamato, ma non in che modo is_callable() && is_object()dice che abbiamo un funtore, ma omette altri tipi callback 27 Funzioni anonime in PHP 5.3
28. La combinazione con altri chiamabili Tre modi per la chiamata (1/3): $o($arg1, $arg2) Vantaggi: velocità Problemi: non funzionerà a meno che si abbiano un funtore, una closure o una chiamata a metodo statico 28 Funzioni anonime in PHP 5.3
29. La combinazione con altri chiamabili Tre modi per la chiamata (2/3): call_user_func($o, $arg1, $arg2) Vantaggi: velocità, funziona con tutti i chiamabili Problemi: se il numero di argomenti è sconosciuto fino al runtime, diventa difficile la gestione 29 Funzioni anonime in PHP 5.3
30. La combinazione con altri chiamabili Tre modi per la chiamata (3/3): call_user_func_array($o, $argv) Vantaggi: funziona con tutti i chiamabili, funziona con un numero di argomenti variabile Problemi: lentezza (impiega fino a 6 volte di più di una chiamata diretta) 30 Funzioni anonime in PHP 5.3
31. Non si può importare $this Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti (Nota: Monkey patching è un modo per ampliare o modificare il runtime codice di linguaggi dinamicisenza alterare la fonte originale codice) 31 Funzioni anonime in PHP 5.3
32. Non si può importare $this Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti È possibile. Solo che non si può usare $this, ciò significa che si presentano dei limiti ai metodi pubblici 32 Funzioni anonime in PHP 5.3
33. Non si può importare $this Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti È possibile. Solo non si può usare $this, il che significa che si presentano dei limiti ai metodi pubblici Inoltre non è possibile auto-dereferenziare le closure assegnate alle proprietà 33 Funzioni anonime in PHP 5.3
34. Esempio: Monkey-Patching class Foo { public function __construct() { $self = $this; $this->bar = function () use ($self) { return get_object_vars($self); }; } public function addMethod($name, Closure $c) { $this->$name = $c; } public function __call($method, $args) { if (property_exists($this, $method) && is_callable($this->$method)) { return call_user_func_array($this->$method, $args); } } } 34 Funzioni anonime in PHP 5.3
37. Aspect Oriented Programming Il codice definisce “aspetti,” oppure codice che taglia attraverso i limiti di più componenti AOP formalizza un modo per congiungere gli aspetti ad altro codice. Spesso, si potrebbe aver bisogno di effettuare il curry su argomenti per mantenere le signature. 37 Funzioni anonime in PHP 5.3
38. Esempio Gestione Eventi $front->events()->attach(’dispatch.router.post’, function($e) use ($cache) { $request = $e->getParam(’request’); if (!$request instanceof Zendttpequest || !$request->isGet()) { return; } $metadata = json_encode($request->getMetadata()); $key = hash(’md5’, $metadata); $backend = $cache->getCache(’default’); if (false !== ($content = $backend->load($key))) { $response = $e->getParam(’response’); $response->setContent($content); return $response; } return; }); 38 Funzioni anonime in PHP 5.3