Outils fonctionnels : closures et générateurs
Trier une liste de prix. Ne garder que ceux au-dessus de vingt. Ajouter la taxe à chacun. Trois tâches différentes, et dans chacune, ce qui compte tient en une seule ligne de logique : comment comparer deux prix, ce que « cher » veut dire, quel est le taux de taxe. PHP vous laisse écrire cette ligne de logique comme une valeur et la confier à une autre fonction, et il vous donne deux façons de l’écrire. Au chapitre 3, vous avez croisé la première en passant : la closure, une fonction sans nom. Une closure peut emporter des variables du code qui l’entoure, à condition de dire lesquelles. La fonction fléchée, la seconde façon, est plus courte et les emporte toute seule.
La deuxième moitié du chapitre s’attaque à un autre problème : les données elles-mêmes. Il arrive que la série que vous parcourez soit trop grosse pour être construite d’un coup, ou trop lente à produire, ou que vous n’ayez besoin que des premiers éléments. Un générateur est une fonction qui rend ses résultats un par un, en marquant une pause entre chacun, au lieu d’assembler tout le tas avant de le rendre. Ça ressemble presque à une fonction ordinaire, et ça change ce qu’une fonction peut faire.
Ensuite, les deux idées passent à l’atelier. L’outil phpgrep du chapitre 14 lit un fichier entier et range chaque ligne trouvée dans un tableau avant d’afficher quoi que ce soit. Parfait pour un petit fichier, un vrai problème pour un gros. Vous réécrirez search() sous forme de générateur, et vous verrez la première ligne apparaître avant que le fichier ait été lu jusqu’au bout.
Le chapitre se termine sur une mesure plutôt que sur un avis : la même tâche écrite en boucle simple, en générateur, puis avec array_map() et array_filter(), chronométrée et pesée, pour que vous choisissiez entre les trois pour une raison, et non parce que l’une d’elles traînait dans le dernier code que vous avez lu.