可変長引数で引数の数を柔軟にしよう

学習の目標

本章では、以下の内容を学習します。

  • 可変長引数の概念と役割を理解する
  • 可変長引数の定義方法と使い方を習得する
  • 可変長引数が配列として扱われる仕組みを理解する
  • 通常の引数と可変長引数を組み合わせる方法を学ぶ
  • 可変長引数を活用した実践的なコード例を理解する

はじめに

前回までに、引数の基本的な使い方、デフォルト値付き引数、キーワード引数について学びました。これらを使うことで、メソッドを様々な状況で柔軟に使えるようになりました。

しかし、これまでの方法では、メソッドが受け取れる引数の数は固定されていました。例えば、足し算を行うメソッドなら、2つの数値を足すのか、3つの数値を足すのかによって、別々のメソッドを定義する必要がありました。

そこで今回は、可変長引数という機能を学びます。可変長引数を使うと、メソッドが受け取る引数の数を自由に変えることができます。例えば、5個の数字を足し合わせたいときも、10個の数字を足し合わせたいときも、1つのメソッドで対応できるようになります。

ファイルの準備

まずは、実習用のファイルを作成しましょう。

VS Codeで新しいファイルを開き、variable_arguments.rbという名前で保存します。これから、このファイルにメソッドを定義していきます。

メソッドの定義

数値を好きな数だけ足し合わせるメソッドを作ってみましょう。次のコードを入力します。

def sum(*numbers)
numbers.sum
end
puts sum(1, 2)
# => 3が表示される
puts sum(1, 2, 3)
# => 6が表示される
puts sum(1, 2, 3, 4, 5)
# => 15が表示される

ここで重要なのは、def sum(*numbers)という部分です。引数名の前に**アスタリスク(*)**を付けることで、その引数は可変長引数として定義されます。可変長引数は、メソッドに渡されたすべての値を配列として受け取ります。

この例では、sumメソッドは任意の数の数値を受け取り、それらの合計を返します。numbers.sumという部分は、numbers配列の要素の合計を計算しています。

このメソッドは、2つの数値を足す場合も、3つの数値を足す場合も、5つの数値を足す場合も、同じメソッドを使って対応できています。引数の数を気にせずメソッドを呼び出すことができるのが、可変長引数の大きなメリットです。

可変長引数の仕組み

可変長引数がどのように扱われているのか、もう少し詳しく見てみましょう。以下のコードを追加します。

def print_numbers(*numbers)
puts "受け取った値の個数: #{numbers.size}"
puts "受け取った値: #{numbers.inspect}"
# 各要素に対して処理を行う例
numbers.each_with_index do |num, index|
puts "#{index + 1}番目の値: #{num}"
end
end
print_numbers(1, 2, 3)

このコードを実行すると、以下のような出力が得られます。

受け取った値の個数: 3
受け取った値: [1, 2, 3]
1番目の値: 1
2番目の値: 2
3番目の値: 3

このように、可変長引数は配列として扱われます。そのため、配列のメソッド(sizeinspecteach_with_indexなど)を使って、受け取った値を操作することができます。

ここで注目すべき点は、可変長引数を使うと、メソッドに渡された値がすべて自動的に配列としてまとめられることです。そのため、メソッド内では配列として扱うことができ、繰り返し処理や合計計算などが簡単にできます。

通常の引数と組み合わせる

可変長引数は、通常の引数と組み合わせることもできます。以下のコードを追加してみましょう。

def greet(message, *names)
names.each do |name|
puts "#{name}さん、#{message}"
end
end
greet("こんにちは", "山田", "田中", "鈴木")

このメソッドでは、最初の引数messageは通常の引数として扱われ、それ以降の引数("山田""田中""鈴木")はすべてnamesという配列として受け取られます。

実行すると、以下のような出力が得られます。

山田さん、こんにちは
田中さん、こんにちは
鈴木さん、こんにちは

このように、通常の引数と可変長引数を組み合わせることで、より柔軟なメソッドを作ることができます。

可変長引数の位置

通常の引数と可変長引数を組み合わせる場合、可変長引数は通常の引数の後に配置する必要があります。これは、どの引数がどの変数に対応するかを明確にするためです。

# 正しい例
def method1(first, second, *others)
# 処理
end
# エラーになる例
def method2(*others, last)
# 処理
end

ただし、Ruby 2.0以降では、キーワード引数を使用する場合は可変長引数の後にキーワード引数を配置することができます。

def method3(*numbers, name:, age:)
# 処理
end
method3(1, 2, 3, name: "山田", age: 30)

このように、可変長引数とキーワード引数を組み合わせることで、より柔軟で読みやすいコードを書くことができます。

可変長引数を使った実践例

可変長引数を使った実践的な例をいくつか見てみましょう。

最大値を求めるメソッド

任意の数の数値から最大値を求めるメソッドを作成してみましょう。

def find_max(*numbers)
if numbers.empty?
nil
else
numbers.max
end
end
puts find_max(5, 3, 9, 1, 7) # => 9
puts find_max(10, 20) # => 20
puts find_max(-5, -10, -3) # => -3
puts find_max # => nil

このメソッドは、任意の数の数値を受け取り、その中の最大値を返します。数値が1つも渡されない場合(つまり、空の配列の場合)はnilを返します。

タグ付きメッセージを作成するメソッド

タグを任意の数だけ付けることができるメッセージ作成メソッドを作ってみましょう。

def create_tagged_message(message, *tags)
if tags.empty?
message
else
tags_text = tags.map { |tag| "##{tag}" }.join(" ")
"#{message} #{tags_text}"
end
end
puts create_tagged_message("今日は晴れです")
# => 今日は晴れです
puts create_tagged_message("おいしいケーキを食べました", "グルメ", "スイーツ", "カフェ")
# => おいしいケーキを食べました #グルメ #スイーツ #カフェ

このメソッドは、メッセージと任意の数のタグを受け取り、タグ付きのメッセージを作成します。タグがない場合は、メッセージをそのまま返します。

可変長引数を使うことで、タグの数を気にせずメソッドを呼び出すことができます。SNSの投稿やブログ記事のタグ付けなどに応用できる例です。

まとめ

本章では、可変長引数について学習しました。以下の内容をマスターできたことと思います。

  • 可変長引数を使うと、メソッドが受け取る引数の数を自由に変えることができる
  • アスタリスク(*)を引数名の前につけることで可変長引数を定義する
  • 可変長引数は配列として扱われ、配列のメソッドを使って操作できる
  • 通常の引数と可変長引数を組み合わせることができる(通常の引数の後に配置する)
  • 可変長引数を使うことで、より柔軟で汎用性の高いメソッドを作ることができる

可変長引数は、引数の数が事前に分からない場合や、様々な数の引数に対応する必要がある場合に非常に便利です。配列のメソッドを活用することで、受け取った値を簡単に処理することができます。これにより、より柔軟で使いやすいコードが書けるようになります。

次の章では、エラーが発生したときに対処する「例外処理」について学んでいきます。

このセクションは有料サブスクリプションへの登録、またはログインが必要です。完全なコンテンツにアクセスするには、料金ページ(/pricing)をご覧ください。購入済みの場合は、ログインしてください。

Starterプランでより詳しく学習

この先のコンテンツを読むにはStarterプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。

作成者:とまだ
Previous
キーワード引数で読みやすくしよう