しおブログ言うてますけど

技術ブログ言うてますけど技術以外のことも発信すると思われ。RubyとかRuby on Railsとか生き方とかジャンルにこだわらず自分の好きなように。初心者なのでお手柔らかに。

配列の多重代入の応用

一般的な多重代入では左辺の変数よりも右辺の個数が多い場合ははみ出した値が切り捨てられる。

a, b, c = 1, 2, 3, 4, 5
a #=>1
b #=>2
c #=>3

45は切り捨てられる...

しかし左辺の変数に*をつけると残りの全要素を配列として受け取ることができる。

a, b, *c = 1, 2, 3, 4, 5
a #=>1
b #=>2
c #=>[3, 4, 5]
dog, cat, *bird = "", "", "", "", "イルカ"
dou #=> 犬
cat #=> 猫
bird #=> ["鳥", "像", "イルカ"]

このように多重代入において、左辺の変数に*をつけると残りの要素を配列として受け取ることができる。

また1つの配列を複数の引数として展開することも*をつければ可能である。

a = []
a.push(1) #=> [1]
a.push(2, 3) #=> [1, 2, 3]

これは一般的な配列に要素を追加する方法。

a = []
b = [2, 3]
a.push(1) #=> [1]
a.push(b) #=> [1, [2, 3]]

ん〜、配列をそのまま代入しようとすると2つの要素(ここでは2, 3)ではなく1つの配列([2, 3])としてaに代入されてしまった。
これを配列を展開して「複数の引数」として追加したい場合、*を使えば「複数の引数」として渡すことが可能である。

例
a = []
b = [2, 3]
a.push(1) #=> [1]
a.push(*b) #=> [1, 2, 3]

1つの配列として追加する場合はa.push(b)としており、複数の引数として追加する場合はa.push(*b)のように*が ついていることがわかる。
挙動としては

a.push(*b)
↓
a.push(*[2, 3])
↓
a.push(2, 3)

これをsplat展開という。

splat展開を使うといろんな形でも配列として代入することができる。

splat展開の例

hoge = *"foobar" #=> ["foobar"]

num = *(1..10) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

symbol = *:symbol #=> [:symbol]

1つの配列として渡しているか複数の引数として渡しているのかもっとわかりやすくまとめてみる。

# hogeメソッドの引数にhogeとhogehogeの2つの引数を渡す
def hoge(hoge, hogehoge)
  puts "#{hoge}, #{hogehoge}"
end

# foobarメソッドに1つの配列([1, 2])を定義する
def foobar
  [1, 2]
end

# hogeメソッドを呼び出して引数にfoobarメソッドを渡すと...
hoge(foobor)
#=> ArgumentError (wrong number of arguments (given 1, expected 2))

#=> 期待している引数は2つだが、1つしか引数がありませんよ、というエラーが出る

#=> *を先頭につけてfoobarを渡すと...
hoge(*foobar)
#=> 1, 2
#=> エラーが出ず、複数の引数として渡されていることがわかる。

splat展開は色々な局面で使えそうだなと感じた。