Ruby : les paramètres de méthode
Par Bounga le samedi, 9 décembre 2006, 21:29 - Documentations - Lien permanent
Les arguments obligatoires
Les méthodes que vous écrivez en Ruby peuvent attendre un argument, plusieurs arguments ou aucun. Vos méthodes peuvent également attendre un nombre variable d'arguments
Lorsque vous appelez une méthode Ruby, vous devez absolument lui passer le bon nombre d'arguments sous peine de lever une exception. Si vous faîtes par exemple :
def ma_methode(x) end ma_methode(1,2,3,4)
alors l'interpréteur Ruby n'hésitera pas à vous lancer une exception ArgumentError: wrong number of arguments (4 for 1) pour vous rappeler que vous n'avez pas passé le bon nombre d'arguments à la méthode.
Les arguments optionnels
Il est possible d'écrire des méthodes auxquelles vous pourrez passer un nombre variable d'arguments. Pour faire cela, il faut mettre une étoile (*) devant le nom du dernier argument comme ici :
def methode_multi_arguments(*x) end
Cette notation permet de dire à l'interpréteur que cette méthode peut être appelée avec un nombre quelconque d'arguments, y compris zéro. En utilisant cette technique, vous obtenez un tableau dans votre méthode. Ici x est donc un tableau que vous pouvez manipuler comme tel. Chaque élément du tableau contient l'un des objets que vous avez passé en paramètre lors de l'appel de méthode.
Vous pouvez également préciser de façon plus fine le nombre d'arguments qu'attend votre méthode en mixant arguments obligatoires et arguments optionnels, comme ici :
def deux_arguments_ou_plus(a, b, *x) end
Dans cet exemple, les arguments a et b sont requis. Le dernier argument (x) quant à lui est optionnel. Vous pouvez ne rien lui passer, lui passer une valeur, ou plusieurs. Les arguments restants seront capturés et stockés dans un tableau nommé x.
Les arguments avec valeur par défaut
Vous pouvez rendre un argument optionnel en lui donnant une valeur par défaut. Si l'argument n'est pas renseigné lors de l'appel de méthode, la valeur par défaut sera utilisée. Voici un exemple :
def argument_par_defaut(a, b, c = 3) puts "Les arguments passés sont : ", a, b, c end argument_par_defaut(1, 2)
qui nous donnera :
Les arguments passés sont : 1 2 3
On voit donc ici qu'aucune valeur n'a été donnée à l'argument c lors de l'appel de méthode et c'est donc la valeur par défaut qui a été utilisée à savoir 3. Si vous aviez passé une troisième valeur, celle-ci aurait été utilisée à la place de la valeur par défaut. Voyons un exemple :
argument_par_defaut(1, 2, 7) Les arguments passés sont : 1 2 7
Les arguments nommés
Ce type d'argument est de plus en plus utilisé par les Rubyistes et a été très largement mis en avant par l'équipe de développement de Ruby on Rails puisque l'API de ce framework repose quasi-uniquement sur l'utilisation d'arguments nommés.
Les arguments nommés ont l'avantage de bien documenter l'utilisation d'une méthode et en facilite l'utilisation. Avec ces arguments, plutôt que de passer les arguments dans un ordre bien précis, on va les passer dans un ordre quelconque en précisant pour chaque argument, son nom. Ainsi, l'interpréteur sera capable d'associer les données à nos variables de façon cohérente.
Pour utiliser les arguments nommés, il faut avoir un minimum d'acquis à propos des tableaux associatif (Hash) et des symboles.
Le but de cette technique étant de permettre des appels de méthode comme suit :
afficher_news(:titre => "Mon titre", :auteur => "Nico", :contenu => "Ici le corps du texte ...")
On voit tout de suite le confort de lecture et d'utilisation que peuvent apporter les arguments nommés. Voyons donc comment les mettre en place :
def afficher_news(specs)
puts "Titre : #{specs[:titre]}" if specs[:titre]
puts "Auteur : #{specs[:auteur]}" if specs[:auteur]
puts "Contenu : #{specs[:contenu]}" if specs[:contenu]
end
Lorsque l'on utilise cette forme, Ruby comprend que l'on veut utiliser un Hash, il associe chaque valeur passée à notre variable en créant un Hash, puis en associant la valeur à la clef que l'on a spécifié. Dans notre méthode, nous n'avons plus qu'à parcourir ces clefs pour récupérer les valeurs et les traiter.
Notez toutefois que si votre Hash ne se trouve pas en dernière position dans la liste d'argument, vous devrez entourer vos symboles d'accolades pour spécifier à l'interpréteur que c'est bien un Hash que vous voulez utiliser.
Si vous utilisez cette façon de faire, quelques méthodes vous seront utiles, notamment specs.has_key?(:la_clef) qui permet de savoir si le Hash contient la clef passée en paramètre, specs.empty? qui permet de savoir si le Hash contient des clefs ou non et specs.each_key { |k| puts k} qui permet de parcourir chaque clef du Hash.
L'ordre des arguments
Si vous utilisez des arguments optionnels ou avec valeur par défaut, l'ordre dans lequel vous les passez est très important et il y a des règles à respecter.
Si vous incluez un argument optionnel (*x), il doit absolument venir après tous les autres arguments. Si l'argument optionnel était placé en plein milieu de la liste d'argument, il serait impossible pour l'interpréteur de savoir comment faire les affectations.
Pour clarifier les choses, je vous propose un tableau récapitulatif des signatures de méthode à utiliser pour mettre en place des arguments obligatoires, optionnels et avec valeur par défaut, tout ceci mixé de différentes façons.
| Types d'arguments | Signature | Exemple d'appel | Affectations |
|---|---|---|---|
| Requis | def m(a, b, c) |
m(1, 2, 3) |
a = 1, b = 2, c = 3 |
| Optionnels | def m(*a) |
m(1, 2, 3) |
a = [1,2,3] |
| Valeur par défaut | def m(a=1) |
m(1, 2, 3)m(2) |
a = 1 a = 2 |
| Requis / Optionnel | def m(a, *b) |
m(1)m(1, 2, 3) |
a = 1, b = [] a = 1, b = [2,3] |
| Requis / Défaut | def m(a, b=1) |
m(2)m(2, 3) |
a = 2, b = 1 a = 2, b = 3 |
| Défaut / Optionnel | def m(a=1, *b) |
m()m(2)m(2, 3, 4) |
a = 1, b = [] a = 2, b = [] a = 2, b = [3,4] |
| Requis / Défaut / Optionnel | def m(a, b=2, *c) |
m(1)m(1, 3)m(1, 3, 4, 5) |
a = 1, b = 2, c = [] a = 1, b = 3, c = [] a = 1, b = 3, c = [4, 5] |
Conclusion
En maîtrisant bien les différents types d'arguments que vous pouvez passer à une méthode, vous aurez toutes les clefs en main pour créer des méthodes plus puissantes, plus dynamiques et plus génériques. Les arguments nommés vous permettront de créer une API facile d'accès pour vos utilisateurs. Les arguments optionnels vous donneront la possibilité de passer et traiter des listes d'arguments, séparés par des virgules ou sous forme de tableau. Un bon usage de ces techniques vous procurera beaucoup de souplesse, il est donc important de bien comprendre ces concepts.
Commentaires
Un seul mot : félicitations.
Voici une documentation claire, précise, bien écrite, et, même si j'avoue ne pas l'avoir parcourue en profondeur, je la verrai bien dans un magazine papier tant elle est bien construite (introduction, premier exemple, extension du premier exemple, autres exemples, tableau récapitulatif, conclusion).
Je te renouvelle mes compliments, Bounga, pour cette documentation.
Merci beaucoup ! Voilà un commentaire qui motive à écrire plus d'articles
J'adhère entièrement au commentaire de Zifro...
Je débute en Ruby et cela fait plaisir de trouver un tel document. La présentation est trés propre et efficace.
Merci =)
Encore merci
J'ai déposé mes articles sur TUTMarks en espérant qu'ils finiront par passer en première page. Pour l'instant très peu de votes pour mes articles :-/, il n'y a peut-être pas de Rubyistes là bas :-).