No, Ruby in realtà non supporta la restituzione di due oggetti. (BTW: restituisci oggetti, non variabili. Più precisamente, restituisci puntatori agli oggetti.)
Tuttavia, supporta l'assegnazione parallela. Se hai più di un oggetto sul lato destro di un compito, gli oggetti vengono raccolti in un Array
:
foo = 1, 2, 3
# is the same as
foo = [1, 2, 3]
Se hai più di un "obiettivo" (variabile o metodo setter) sul lato sinistro di un compito, le variabili vengono associate agli elementi di un Array
sul lato destro:
a, b, c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary[2]
Se il lato destro non è un Array
, verrà convertito in uno utilizzando il to_ary
metodo
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]
E se mettiamo insieme i due, lo otteniamo
a, b, c = d, e, f
# is the same as
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]
Correlato a questo è l'operatore splat sul lato sinistro di un compito. Significa "prendi tutti gli elementi rimanenti del Array
lato destro":
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
E, ultimo ma non meno importante, le assegnazioni parallele possono essere annidate usando le parentesi:
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]
Quando si return
da un metodo o next
o break
da un blocco, Ruby tratterà di questo tipo, di come il lato destro di una cessione, in modo
return 1, 2
next 1, 2
break 1, 2
# is the same as
return [1, 2]
next [1, 2]
break [1, 2]
A proposito, questo funziona anche negli elenchi di parametri di metodi e blocchi (con metodi più rigidi e blocchi meno rigidi):
def foo(a, (b, c), d) p a, b, c, d end
bar {|a, (b, c), d| p a, b, c, d }
Il fatto che i blocchi siano "meno rigidi" è ad esempio ciò che fa Hash#each
funzionare. In realtà è yield
un singolo elemento a due elementi Array
chiave e valore per il blocco, ma di solito scriviamo
some_hash.each {|k, v| }
invece di
some_hash.each {|(k, v)| }