lundi 2 décembre 2013

Les paramètres nommés

Tout comme les variables souillées, les paramètres nommés sont un vieux serpent de mer en PHP. A l'heure où j'écris ces lignes, une RFC:named_params est en cours de discussion pour une possible intégration dans PHP 5.6.
A quoi peut bien servir ces paramètres nommés ? Je vais essayé de faire un point sur le sujet.

Voici un exemple de ce que pourrait être une utilisation des paramètres nommés :
function affiche($string, $flags = 0, $charset = 'UTF-8', $encode = false) {
  // du code ...
}

affiche(string => 'ma chaîne', encode => true);

Les paramètres nommés ne sont pas une opportunité pour se faire plaisir en réordonnant les paramètres, même si c'est possible; il faut y voir 2 intérêts majeurs :

  • Eviter de redéfinir les paramètres optionnels
  • Améliorer la lecture en identifiant l'objet d'un paramètre, sans connaître la signature de la fonction

Paramètres optionnels

Dans l'exemple précédent, sans les paramètres nommés, l'appel à la fonction aurait dû s'écrire comme ceci : 

affiche('ma chaîne', 0, 'UTF-8', true);

Comme on peut le voir, les deux paramètres "$flags" et "$charset" doivent être posés exactement tel que l'exige la fonction afin de définir "$encode". Cette contrainte nécessite donc de connaître la signature exacte de la fonction, pour poser les bons paramètres par défaut.

Du coup, on hésite beaucoup à définir trop de paramètres par défaut, et lorsqu'on le fait, on essaye le plus que possible de définir ces paramètres par ordre probable de fréquence d'utilisation.

Si on voulait le réaliser en PHP, on devrait donc utiliser un tableau comme suit :

/**
 * @param string $string
 * @param int $flags
 * @param string $charset
 * @param boolean $encode
 */
function affiche(array $parameters) {
  if (!isset($parameters['string'])) throw new \RuntimeException('Paramètres $string manquant');
  if (!isset($parameters['flags'])) $parameters['flags'] = 0;
  if (!isset($parameters['charset'])) $parameters['charset'] = 'UTF-8';
  if (!isset($parameters['encode'])) $parameters['encode'] = false;
  // Du code ...
}

affiche([$string => 'ma chaîne', $encode => true]);

L'appel n'est pas trop compliqué, par contre, la déclaration de la fonction n'est pas des plus simples, sans parler du problème que l'on pourrait avoir avec nos IDE préférés et l'auto-complétion (d'où la présence de tags PHPDoc) !

Avec une syntaxe de paramètres nommés, ce genre de problème serait bien vite oublié.

Améliorer la lecture

Dans l'exemple suivant :
affiche('ma chaîne', 0, 'UTF-8', true);

A la lecture de cette ligne, à moins de connaître la fonction par coeur, il n'est pas simple de savoir à quoi servent le "0" et le "true" (on se doute, plus ou moins, des deux autres paramètres).

Avec des paramètres nommés, et en supposant que les 4 n'ont pas de valeur par défaut, on écrirait :

affiche(string => 'ma chaîne', flags => 0, charset => 'UTF-8', encode => true);

Ainsi, en dehors de "flags" qui n'est pas très explicite (je n'aime pas d'ailleurs ce genre de paramètre abscons), on comprend un peu plus l'utilité de chaque paramètre.

Sans les paramètres nommés, il est toujours possible d'augmenter la lisibilité du code comme suit :

affiche($string = 'ma chaîne', $flags = 0, $charset = 'UTF-8', $encode = true);

Ou alors
affiche(/*$string*/'ma chaîne', /*$flags*/0, /*$charset*/'UTF-8', /*$encode*/true);

J'aime bien le premier cas, mais cela consomme de la mémoire inutilement, avec un infime impact sur les performances à haut débit.

Autant, en ce qui me concerne, je n'ai rien à faire des variables souillées, autant les paramètres nommés apporteraient un réel confort dans l'appel de nos fonctions. Alors, si vous en avez les moyens, militez pour que la RFC:named_params soit adoptée dans la version PHP 5.6 !

Aucun commentaire:

Enregistrer un commentaire