No, Ruby no admite la devolución de dos objetos. (Por cierto: devuelve objetos, no variables. Más precisamente, devuelve punteros a objetos).
Sin embargo, admite la asignación en paralelo. Si tiene más de un objeto en el lado derecho de una tarea, los objetos se recopilan en un Array
:
foo = 1, 2, 3
# is the same as
foo = [1, 2, 3]
Si tiene más de un "objetivo" (variable o método de establecimiento) en el lado izquierdo de una asignación, las variables se unen a elementos de un Array
en el lado derecho:
a, b, c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary[2]
Si el lado derecho no es un Array
, se convertirá en uno usando el to_ary
método
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]
Y si juntamos los dos, obtenemos eso
a, b, c = d, e, f
# is the same as
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]
Relacionado con esto está el operador de símbolos en el lado izquierdo de una asignación. Significa "tomar todos los elementos sobrantes del Array
lado derecho":
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
Y por último, pero no menos importante, las asignaciones paralelas se pueden anidar usando paréntesis:
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]
Cuando return
a partir de un método o next
o break
de un bloque, Ruby va a tratar este tipo de como el lado derecho de una asignación, por lo
return 1, 2
next 1, 2
break 1, 2
# is the same as
return [1, 2]
next [1, 2]
break [1, 2]
Por cierto, esto también funciona en listas de parámetros de métodos y bloques (siendo los métodos más estrictos y los bloques menos estrictos):
def foo(a, (b, c), d) p a, b, c, d end
bar {|a, (b, c), d| p a, b, c, d }
Los bloques que son "menos estrictos" es, por ejemplo, lo que hace que Hash#each
funcione. En realidad, yield
es un solo elemento Array
de dos claves y valor para el bloque, pero generalmente escribimos
some_hash.each {|k, v| }
en vez de
some_hash.each {|(k, v)| }