Ruby
プロを目指す人のためのRuby入門

はじめに

この記事は書籍「プロを目指す人のためのRuby入門」に掲載できなかったトピックを著者自らが紹介するアドベントカレンダーの9日目です。
本文に出てくる章番号や項番号は書籍の中で使われている番号です。

今回は*を使って配列の一部を取り出す方法を説明します。

*と変数の代入の関係

あまり積極的に使うテクニックではありませんが、*と変数の代入の関係について、少し詳しく見ていきましょう。

4.7.5項では左辺の変数に*を付けて残りの全要素を配列として受け取るコードを紹介しました。

e, *f = 100, 200, 300
e #=> 100
f #=> [200, 300]

*は最初の変数に付けることもできます。実際にやってみましょう。

*e, f = 100, 200, 300
e #=> [100, 200]
f #=> 300

ご覧のとおり、最初の要素から最後の一つ前の要素がeに、最後の要素がfに代入されました。

最初や最後だけでなく、次のように途中の変数に*を付けて代入することも可能です。

a, b, *c, d, e = 1, 2, 3, 4, 5, 6
a #=> 1
b #=> 2
c #=> [3, 4]
d #=> 5
e #=> 6

配列の要素が左辺の変数よりも少ない場合は、*が付いていない変数から優先的に代入されます。

# 変数と配列の要素数が同じ
a, *b, c = 1, 2, 3
a #=> 1
b #=> [2]
c #=> 3

# 配列の要素数が1つ少ない
a, *b, c = 1, 2
a #=> 1
b #=> []
c #=> 2

# 配列の要素数が2つ少ない
a, *b, c = 1
a #=> 1
b #=> []    
c #=> nil

ちなみに、上のような挙動は可変長引数を持つメソッドに引数を渡す場合も同じです。

def m(a, *b, c)
  puts "a: #{a}, b: #{b}, c: #{c}"
end

m(1, 2, 3) #=> a: 1, b: [2], c: 3
m(1, 2)    #=> a: 1, b: [], c: 2
# 引数は最低2つ必要なので、引数が1つの場合はエラー
m(1)       #=> ArgumentError: wrong number of arguments (given 1, expected 2+)

無理に*を駆使したコードを書く必要はありませんが、頭の片隅に置いておくと何かの際に役立つかもしれません。

次回予告

次回は範囲式を使ったフリップフロップを紹介します。