Нет, на самом деле Ruby не поддерживает возврат двух объектов. (Кстати: вы возвращаете объекты, а не переменные. Точнее, вы возвращаете указатели на объекты.)
Однако он поддерживает параллельное присвоение. Если у вас есть более одного объекта в правой части назначения, объекты собираются в Array
:
foo = 1, 2, 3
foo = [1, 2, 3]
Если у вас есть более одной «цели» (переменная или метод установки) в левой части присваивания, переменные привязываются к элементам Array
в правой части:
a, b, c = ary
a = ary[0]
b = ary[1]
c = ary[2]
Если правая часть не является Array
, она будет преобразована в одну с помощью to_ary
метода
a, b, c = not_an_ary
ary = not_an_ary.to_ary
a = ary[0]
b = ary[1]
c = ary[2]
И если мы сложим их вместе, мы получим
a, b, c = d, e, f
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]
С этим связан оператор splat в левой части присваивания. Это означает "взять все оставшиеся элементы в Array
правой части":
a, b, *c = ary
a = ary[0]
b = ary[1]
c = ary.drop(2)
И последнее, но не менее важное: параллельные назначения можно вкладывать в круглые скобки:
a, (b, c), d = ary
a = ary[0]
b, c = ary[1]
d = ary[2]
a = ary[0]
b = ary[1][0]
c = ary[1][1]
d = ary[2]
Когда вы переходите return
из метода next
или break
блока, Ruby будет рассматривать это как правую часть присваивания, поэтому
return 1, 2
next 1, 2
break 1, 2
return [1, 2]
next [1, 2]
break [1, 2]
Кстати, это также работает в списках параметров методов и блоков (с более строгими методами и менее строгими блоками):
def foo(a, (b, c), d) p a, b, c, d end
bar {|a, (b, c), d| p a, b, c, d }
Например, «менее строгие» блоки делают Hash#each
работу. Это на самом деле yield
са одного из двух элементов Array
ключа и значения в блок, но мы обычно пишем
some_hash.each {|k, v| }
вместо того
some_hash.each {|(k, v)| }