Non, Ruby ne prend pas en charge le retour de deux objets. (BTW: vous renvoyez des objets, pas des variables. Plus précisément, vous renvoyez des pointeurs vers des objets.)
Cependant, il prend en charge l'affectation parallèle. Si vous avez plusieurs objets sur le côté droit d'une affectation, les objets sont rassemblés dans un Array
:
foo = 1, 2, 3
# is the same as
foo = [1, 2, 3]
Si vous avez plus d'une "cible" (variable ou méthode de définition) sur le côté gauche d'une affectation, les variables sont liées aux éléments d'un Array
sur le côté droit:
a, b, c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary[2]
Si le côté droit n'est pas un Array
, il sera converti en un à l'aide de la to_ary
méthode
a, b, c = not_an_ary
# is the same as
ary = not_an_ary.to_ary
a = ary[0]
b = ary[1]
c = ary[2]
Et si nous mettons les deux ensemble, nous obtenons cela
a, b, c = d, e, f
# is the same as
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]
L'opérateur splat sur le côté gauche d'une affectation est lié à cela. Cela signifie "prendre tous les éléments de gauche sur le Array
côté droit":
a, b, *c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary.drop(2) # i.e. the rest of the Array
Enfin, les affectations parallèles peuvent être imbriquées en utilisant des parenthèses:
a, (b, c), d = ary
# is the same as
a = ary[0]
b, c = ary[1]
d = ary[2]
# which is the same as
a = ary[0]
b = ary[1][0]
c = ary[1][1]
d = ary[2]
Lorsque vous return
utilisez une méthode ou next
ou break
un bloc, Ruby traitera ce genre de chose comme le côté droit d'une affectation, donc
return 1, 2
next 1, 2
break 1, 2
# is the same as
return [1, 2]
next [1, 2]
break [1, 2]
À propos, cela fonctionne également dans les listes de paramètres de méthodes et de blocs (les méthodes étant plus strictes et les blocs moins stricts):
def foo(a, (b, c), d) p a, b, c, d end
bar {|a, (b, c), d| p a, b, c, d }
Les blocs étant "moins stricts", c'est par exemple ce qui fait Hash#each
fonctionner. Il s'agit en fait d' yield
un seul élément à deux éléments Array
clé et valeur du bloc, mais nous écrivons généralement
some_hash.each {|k, v| }
au lieu de
some_hash.each {|(k, v)| }