Ruby

戻り値が複数ある場合の変数代入

More than 3 years have passed since last update.

戻り値が複数ある場合の、受け取り方による値の違い

def get_multi_return
  return 'A','B','C'
end

基本ルール

戻り値と受け取り側の数が同じ場合

素直に1つずつ受け取る

a, b, c = get_multi_return
a #=> 'A'
b #=> 'B'
c #=> 'C'

受け取り側の数が1つの場合

全ての戻り値を持った配列として受け取る

m = get_multi_return
m #=> ['A', 'B', 'C']

受け取り側の数が少ない場合

前から順番に受け取り、残りは捨てられる

p, q = get_multi_return
p #=> 'A'
q #=> 'B'

受け取り側の数が多い場合

前から順に受け取り、足りない分はnilが入る

p, q, r, s = get_multi_return
p #=> 'A'
q #=> 'B'
r #=> 'C'
s #=> nil

「*」をつけると明示的に配列で受け取れる

受け取られなかった残りの値を持った配列になる

x, *y = get_multi_return
x #=> 'A'
y #=> ['B', 'C']

配列について

戻り値が足りない場合は空の配列になる

a, b, c, *m = get_multi_return
a #=> 'A'
b #=> 'B'
c #=> 'C'
m #=> []

配列は最後でなくても良い

最初でも

*x, y = get_multi_return
x #=> ['A', 'B']
y #=> 'C'

間でも

a, *x, c = get_multi_return
a #=> 'A'
x #=> ['B']
c #=> 'C'

優先度は低い

受け取り側の数が多い場合は、配列でないものが優先的に値を受け取る
(受け取り側の数が同じ、または少ない場合は、上2つのように平等に前から受け取る)

a, *x, b, c = get_multi_return
a #=> 'A'
x #=> []
b #=> 'B'
c #=> 'C'

配列は複数指定できない

*m, *n = get_multi_return
 #=> SyntaxError: unexpected tSTAR

まとめ

・受け取り側の変数の数 <= 戻り値の数

 => 「*」付きの変数があれば、そこにn個の値を入れるとして、戻り値が余らないように前から値を入れる
   「*」付きの変数がなければ、前から値を1つずつ入れ、余った戻り値は捨てる

・受け取り側の変数の数 > 戻り値の数

 => 「*」付きの変数があれば[]を入れ、それ以外の変数に前から値を入れ、足りない分はnilを入れる

・・・日本語難しい