Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

Organization

メソッドの引数をアスタリスク1文字にするイディオム

はじめに

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

今回はメソッドの引数をアスタリスク1文字にするイディオムを紹介します。

必要な前提知識

「プロを目指す人のためのRuby入門」の第7章まで読み終わっていること。

メソッドの引数をアスタリスク1文字にするイディオム

4.4.7項でも説明したとおり、メソッド定義で引数の前に*を使うとその引数が可変長引数になります。

def greeting(*names)
  "#{names.join('と')}、こんにちは!"
end
greeting('田中さん')                       #=> "田中さん、こんにちは!"
greeting('田中さん', '鈴木さん')            #=> "田中さんと鈴木さん、こんにちは!"
greeting('田中さん', '鈴木さん', '佐藤さん') #=> "田中さんと鈴木さんと佐藤さん、こんにちは!"

可変長引数は次のように引数名を省略することもできます。

def greeting(*)
  # 中身はいったん空にする
end
greeting('田中さん')                       #=> nil
greeting('田中さん', '鈴木さん')            #=> nil
greeting('田中さん', '鈴木さん', '佐藤さん') #=> nil

さて、このままだと何もメリットがないように見えますが、以下のような条件が揃った場合にアスタリスク1文字だけの可変長引数が利用されることがあります。

  • サブクラスがsuperを使ってスーパークラスの同名メソッドを呼び出す
  • 渡された引数は全部そのままスーパークラスに渡す
  • サブクラスのメソッド内では引数を利用しない

たとえば次のようなコードです。

class Product
  attr_reader :name, :price

  def initialize(name, price)
    @name = name
    @price = price
  end
end

class DVD < Product
  # 明示的にname, priceという引数を書く代わりに、*だけで済ませる
  def initialize(*)
    # 渡された引数を全部そのままスーパークラスに渡す
    super

    # サブクラスで必要な初期化処理を書く
  end
end

dvd = DVD.new('A great movie', 1000)
dvd.name  #=> "A great movie"
dvd.price #=> 1000

サブクラス側の実装は可変長引数なのでいくつでも引数を渡せますが、スーパークラス側はそうではないため、結果的に引数の数は2個に制限されます。

DVD.new('A great movie', 1000, 'foo')
#=> ArgumentError: wrong number of arguments (given 3, expected 2)

superの使い方については「7.6.5 superでスーパークラスのメソッドを呼び出す」の項で説明したので、忘れた方はもう一度読み直してください。

少しトリッキーなので、初心者のうちはわざわざこのような書き方を真似する必要はありません。
ですが、gemのコードを読んでいると、ときどきアスタリスク1文字の引数が登場することがあるので、知っておくとコードリーディングの際に役立つ場合があります。

次回予告

次回はローカル変数の宣言と代入の関係について説明します。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
14
Help us understand the problem. What are the problem?