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.