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 Arraysur 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_arymé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 Arraycô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 returnutilisez une méthode ou nextou breakun 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#eachfonctionner. Il s'agit en fait d' yieldun seul élément à deux éléments Arrayclé et valeur du bloc, mais nous écrivons généralement
some_hash.each {|k, v| }
au lieu de
some_hash.each {|(k, v)| }