Ruby est l’un des langages les plus utilisés sur le Web. Nous avons lancé une nouvelle série de screencast ici sur Nettuts + qui vous présentera Ruby, ainsi que les formidables cadres et outils associés au développement de Ruby. Dans ce chapitre, nous allons parler de blocs et d'itérateurs.
Dans la dernière leçon, nous avons parlé de boucles. En fait, vous n'utiliserez pas trop de boucles dans Ruby, à cause d'une fonctionnalité appelée des blocs (et à la suite de blocs-itérateurs). Pour vous rafraîchir la mémoire, examinez les deux appels de méthode suivants (vous pouvez essayer ceci dans IRB):
name = "Joe" name.reverse # => "eoJ" name.concat ("le plombier") # => "Joe le plombier"
Comme vous le savez, les parenthèses après l'appel de la méthode sont généralement facultatifs. Nous allons apprendre aujourd'hui quand ils sont nécessaires.
Donc, voici les parties d'un appel de méthode:
prénom
au dessus de.sens inverse
ou concat
au dessus de." Le plombier"
dans le deuxième exemple ci-dessus.Les trois premières parties sont nécessaires, évidemment. Les arguments et le bloc de code sont facultatifs. Quel est ce bloc de code? Regardez cet exemple, et ensuite nous en discuterons:
sites = ["net", "psd", "mobile"] sites.map! faire | site | site + = ".tutsplus.com" sites d'extrémité # => ["net.tutsplus.com", "psd.tutsplus.com", "mobile.tutsplus.com"]
Dans ce cas, le tableau des sites
est le récepteur; la méthode est carte!
. Ensuite nous avons le bloc. Si le bloc est sur plusieurs lignes, vous pouvez utiliser les mots-clés faire
et fin
pour le délimiter. Si vous le mettez sur une seule ligne, vous pouvez utiliser des accolades (elles fonctionnent également pour les blocs multilignes).
Après l’ouverture du bloc, nous avons les paramètres du bloc, dans des tuyaux ( |
). Cela dépend vraiment de la méthode que vous exécutez. L'utilisation la plus courante des blocs se trouve dans les méthodes itérateur. Le paramètre block sera donc l'élément en cours dans la boucle. Si cela semble assez abstrait, nous allons faire quelques exemples.
Nous allons commencer par examiner les itérateurs de tableaux, car ce sont les éléments les plus couramment bouclés..
Au lieu d'utiliser une boucle for, vous utiliserez probablement chaque
:
sites = ["net", "psd", "mobile"] sites.each | site | met "# site .tutsplus.com" # net.tutsplus.com # psd.tutsplus.com # mobile.tutsplus.com
C'est comme faire une boucle for; un par un, chaque article dans des sites
sera affecté au paramètre de bloc site
; ensuite, le code à l'intérieur du bloc sera exécuté.
Si vous êtes curieux, le chaque
méthode retourne le tableau d'origine.
Parfois, vous voudrez renvoyer une valeur du bloc. Ce n'est pas difficile à faire, si vous utilisez la bonne méthode.
# assume les sites ci-dessus sites = sites.map do | s | "# s .tutsplus.com" end
le carte
La méthode collecte toutes les valeurs renvoyées à chaque itération du bloc. Ensuite, un tableau de ces valeurs est renvoyé par la méthode. Dans ce cas, nous réaffectons le des sites
variable au nouveau tableau.
Il y a une meilleure façon de faire cela, cependant. Plusieurs méthodes Ruby ont des doublons avec le point d'exclamation (ou bang); cela signifie qu'ils sont destructeurs: ils remplacent la valeur sur laquelle ils travaillent. Donc, ce qui précède pourrait être fait de cette façon:
sites.map! | site_prefix | "# site_prefix .tutsplus.com"
À présent, des sites
sera le tableau de valeurs renvoyé par le bloc.
Cependant, plus que les tableaux ont des méthodes d'itérateur. Les chiffres ont une assez cool fois
méthode:
5 fois | i | met "Numéro de boucle # i" et # Numéro de boucle 0 # Numéro de boucle 1 # Numéro de boucle 2 # Numéro de boucle 3 # Numéro de boucle 4
À mesure que vous continuez à coder Ruby, vous découvrirez de nombreuses méthodes utiles utilisant des blocs. Voyons maintenant comment créer nos propres blocs.
Maintenant que vous savez utiliser des blocs, voyons comment écrire des méthodes qui en tirent parti. Voici deux autres informations de bloc que vous n'avez pas encore apprises:
Voici ce qui se passe lorsque vous appelez une méthode qui prend un bloc. En coulisse, Ruby exécute un code de méthode, cédant ensuite au code de bloc. Après cela, le contrôle est retourné à la méthode. Regardons ça.
Comme la plupart des fonctions d'itérateur simples sont intégrées à Ruby, nous en «réécrirons» une. Faisons le chaque
méthode sur les tableaux:
classe Array def each2 i = 0; tandis que self [i] cède self [i] i + = 1 end self end
Comme vous pouvez le constater, ceci n’est qu’une méthode normale. Rappelez-vous que dans une méthode d'instance, le soi
mot-clé fait référence à l'instance de la classe, dans ce cas, Tableau
. Dans la méthode, nous utilisons une boucle while pour parcourir les éléments du tableau. Ensuite, dans la boucle, nous utilisons le rendement
mot-clé. Nous le transmettons moi [i]
; cela finira par être le paramètre de bloc. Après cela, nous incrémentons je
pour la boucle et continuer.
Si nous voulions que cette méthode retourne le tableau de valeurs renvoyées par le bloc, nous pourrions simplement capturer la valeur renvoyée de rendement
et retourner que, au lieu de soi
, nous retournons ce tableau.
class Array def each2_returning_new_values i = 0; new_vals = []; tandis que self [i] new_vals [i] = céder self [i] i + = 1 fin new_vals end end
Terminons en parlant de méthodes. Nous savons que l'utilisation de parenthèses est facultative… la plupart du temps. Voici quand vous devez utiliser la parenthèse lorsque la méthode appelle.
Parfois, vous aurez les deux paramètres de méthode et un bloc.
obj.some_method "param" | x | #block code here
Ce que je viens de faire ne fonctionnera pas; dans ce cas, nous devons utiliser des parenthèses, car sinon le bloc est associé au dernier paramètre. Ce n'est le cas que si vous utilisez les accolades pour délimiter le bloc; si tu utilises faire
- fin
, les parenthèses ne sont pas obligatoires.
L'autre temps nécessaire entre parenthèses est lorsque vous passez un hachage littéral (et non une variable pointant vers un hachage) en tant que premier paramètre de la méthode. Ruby va penser que c'est un bloc, à cause de l'accolade
arr.push : name => "Andrew" # échoue! arr.push (: name => "Andrew") # Passes