環境
Ruby2.6
はじめに
自分が以前使っていたVBでは、関数での引数の受け渡しには、デフォルトではByValが指定されており、値渡しが基本であった。しかし、引数のパラメータに、ByRefを設定することで、参照渡しができるようになっていた。しかし、Rubyではどうも、参照渡しがそもそもできない仕様になっている。「うーん、これができないのか、使えんなー。」という印象であったが、Rubyには参照渡しができない代わりに、戻り値が複数選択できるようになっていた。思い直した。「なるほど、これはいいかも知れない。」このような仕様になっているのであれば、引数による参照渡しは確かに不要であった。戻り値を複数選択した場合、どのような動きになるのか、確認してみた。
動作確認
普通に、戻り値を1つだけ指定する場合です。戻り値でよく使われる、Boolean型を戻り値にしています。メソッド内の処理が正常終了したか、異常終了したか(更新処理で失敗して例外に飛んだなど)を判断するときによく使われるかと思います。
def test_return?(a)
if a > 1
return true
else
return false
end
end
puts test_return?(1) ? "OK" : "NG" # => NG
puts test_return?(2) ? "OK" : "NG" # => OK
次のように、戻り値を複数指定することができます。第一戻り値はBoolean型で返し、第二戻り値は変数で返すといったことができます。つまり、これで参照渡しが実現できています。VBを使っていれば、参照渡しはメソッドの引数を使ってやり取りをするものだと思っていたのですが、固定概念が外れました。
def test_return(a)
return true, a + 1
end
x, y = test_return(1)
puts "#{x} #{y}" # => true 2
戻り値にはさまざまな型を渡すことができます。
def test_return(a)
return true, a + 1, a.to_s, a.to_s.to_sym, a.to_s.split
end
a, b, c, d, e = test_return(1)
puts "#{a} #{b} #{c} #{d} #{e}" # => true 2 1 1 ["1"]
戻り値が1つしかないのに、受け取りの変数を複数した場合は、戻り値がない変数にはnilがセットされます。
def test_return(a)
return a
end
a, b, c = test_return(1)
puts "#{a} #{b} #{c} " # => 1
puts b.nil? && c.nil? # true
戻り値が複数あるが、受け取る変数が1つしかない場合は、配列で戻ります。
def test_return(a)
return a, a+1, a+2
end
a = test_return(1)
puts "#{a}" # => [1,2,3]
puts "#{a[0]} #{a[1]} #{a[2]}" # => 1 2 3
配列で戻るのであれば、戻り値を配列で渡してやっても、結果的には同じになります。
def test_return(a)
ary = []
ary << a << a+1 << a+2
return ary
end
a = test_return(1)
puts "#{a}" # => [1,2,3]
puts "#{a[0]} #{a[1]} #{a[2]}" # => 1 2 3