Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

この記事は書籍「プロを目指す人のための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文字の引数が登場することがあるので、知っておくとコードリーディングの際に役立つ場合があります。

次回予告

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

jnchito
SIer、社内SEを経て、ソニックガーデンに合流したプログラマ。 「プロを目指す人のためのRuby入門」の著者。 http://gihyo.jp/book/2017/978-4-7741-9397-7 および「Everyday Rails - RSpecによるRailsテスト入門」の翻訳者。 https://leanpub.com/everydayrailsrspec-jp
https://blog.jnito.com/
sonicgarden
「お客様に無駄遣いをさせない受託開発」と「習慣を変えるソフトウェアのサービス」に取り組んでいるソフトウェア企業
http://www.sonicgarden.jp
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした