Ruby練習問題3-5:モジュールを使ってみよう

記事内に商品プロモーションを含む場合があります

Rubyの初心者向け問題3-5:モジュールを使ってみよう

この問題を解くために必要な知識:
【レベル1~2の知識】
コメントの書き方、変数と定数、基本データ型、四則演算と演算子、入力と出力、文字列操作、分岐処理(if、if~else、elsif、case)、繰り返し処理(for、while、until、each)、範囲(Range)、例外処理(begin-rescue-end)、配列(Array)、ハッシュ(Hash)、コレクション操作(配列、ハッシュの操作)、Enumerableモジュール

【レベル3の知識】
メソッドの定義と呼び出し、メソッドの戻り値、クラスの定義と使用、コンストラクタ、クラスの継承、モジュールの定義と使用、ミックスイン

<<前の問題 問題集Top 次の問題>>

Rubyの文法「モジュールの定義と使用」とは

ここではモジュールの定義と使用の意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。



Rubyでは、モジュールを使ってコードの再利用や機能の整理を行うことができます。

モジュールは、クラスのようにメソッドや定数をまとめるためのものですが、インスタンス化(newメソッドでオブジェクトを作成すること)はできません

代わりに、モジュールを使ってクラスに機能を共有させたり、名前空間を提供することができます。

モジュールの定義

まず、Rubyでのモジュールの定義方法を見てみましょう。

module Greeter
  def hello
    "Hello"
  end
end

この例では、Greeterというモジュールを定義し、その中にhelloメソッドを作成しています。

このメソッドは、後で他のクラスで再利用することができます。

モジュールの使用 – include

モジュールをクラスで使用するには、includeキーワードを使います。

includeを使うことで、そのクラスの中にモジュールのメソッドを取り込むことができます。

class Person
  include Greeter
end

person = Person.new
puts person.hello  # => "Hello"

PersonクラスにGreeterモジュールをincludeすることで、helloメソッドがPersonクラス内で使えるようになります。

person.helloを呼び出すと、”Hello”が表示されます。

モジュールを使う利点

モジュールを使うことで、複数のクラスに共通する機能をまとめて再利用することができます。

たとえば、異なるクラスに同じメソッドを持たせたい場合に、コードを重複させずに済みます。

また、モジュールを使うと名前の衝突を避けることもできます。

モジュール内で定義したメソッドは、そのモジュールを使わなければアクセスできないため、他のクラスやモジュールとメソッド名が重複しても問題ありません。

モジュールと名前空間

モジュールは名前空間を提供する役割も持っています。

名前空間を使うことで、異なるクラスやモジュールで同じ名前のメソッドや定数を定義しても、それらが衝突することなく使えます。

module Greeter
  def hello
    "Hello from Greeter"
  end
end

module Farewell
  def hello
    "Goodbye"
  end
end

class Person
  include Greeter
  include Farewell
end

person = Person.new
puts person.hello  # => "Goodbye"

この例では、GreeterFarewellという2つのモジュールをPersonクラスにincludeしています。

最後にincludeしたFarewellhelloメソッドが呼ばれます。

まとめ

モジュールは、Rubyでコードを整理し、再利用するための強力なツールです。

クラスに直接メソッドを追加するのではなく、モジュールを使って機能を分割することで、コードの管理が簡単になり、バグも減らせます。

特に大規模なプログラムでは、モジュールを使って機能を分割することで、保守性の高いコードを書けるようになります。 ​



Ruby練習問題3-5_モジュールを使って単位換算プログラムを作ろう

距離と重さの単位換算を行うプログラムを作成しましょう。

ユーザーが入力した数値を以下のように換算させます。

  • キロメートル ⇔ マイル
  • キログラム ⇔ ポンド

各換算機能はモジュールとして定義され、メインの換算クラスで使用されます。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • DistanceConverterモジュールを定義し、キロメートルをマイルに換算するメソッドとマイルをキロメートルに換算するメソッドを持つこと。
  • WeightConverterモジュールを定義し、キログラムをポンドに換算するメソッドとポンドをキログラムに換算するメソッドを持つこと。
  • Converterクラスを定義し、ユーザーからの入力を受け取り、適切な単位換算を行うメソッドを実装すること。
  • コンストラクタを使って、必要な初期化を行うこと。
  • ユーザーからの入力を利用して、単位換算機能を実行し、結果を表示すること。
  • 1キロメートル = 0.621371マイル、1マイル = 1.60934キロメートル
  • 1キログラム = 2.20462ポンド、1ポンド = 0.453592キログラム

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

単位換算プログラムを初期化しました。
換算したい単位を選択してください: 1. キロメートルをマイル, 2. マイルをキロメートル, 3. キログラムをポンド, 4. ポンドをキログラム
1
キロメートルを入力してください:
10
結果: 6.21371 マイル
続けますか? (y/n)
y
換算したい単位を選択してください: 1. キロメートルをマイル, 2. マイルをキロメートル, 3. キログラムをポンド, 4. ポンドをキログラム
3
キログラムを入力してください:
5
結果: 11.0231 ポンド
続けますか? (y/n)
n
単位換算プログラムを終了します。

----- ↑出力される結果の例↑ -----

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1.DistanceConverterモジュールの定義
 1-1. KM_TO_MILES定数の定義(キロメートルをマイルに変換する定数)
 1-2. MILES_TO_KM定数の定義(マイルをキロメートルに変換する定数)
 1-3. km_to_miles(km)メソッドの定義(キロメートルをマイルに変換)
 1-4. miles_to_km(miles)メソッドの定義(マイルをキロメートルに変換)

2.WeightConverterモジュールの定義
 2-1. KG_TO_POUNDS定数の定義(キログラムをポンドに変換する定数)
 2-2. POUNDS_TO_KG定数の定義(ポンドをキログラムに変換する定数)
 2-3. kg_to_pounds(kg)メソッドの定義(キログラムをポンドに変換)
 2-4. pounds_to_kg(pounds)メソッドの定義(ポンドをキログラムに変換)

3.Converterクラスの定義
 3-1. initializeメソッドの定義
  3-1-1. プログラムの初期化メッセージを表示
 3-2. perform_conversionメソッドの定義
  3-2-1. 単位換算の選択肢を表示
  3-2-2. ユーザーの入力を取得し、choiceに格納
  3-2-3. case文を使用して選択肢に応じた換算処理を行う
   3-2-3-1. キロメートルからマイルへの換算(DistanceConverterモジュールのkm_to_milesメソッドを使用)
   3-2-3-2. マイルからキロメートルへの換算(DistanceConverterモジュールのmiles_to_kmメソッドを使用)
   3-2-3-3. キログラムからポンドへの換算(WeightConverterモジュールのkg_to_poundsメソッドを使用)
   3-2-3-4. ポンドからキログラムへの換算(WeightConverterモジュールのpounds_to_kgメソッドを使用)
  3-2-4. 無効な選択に対してエラーメッセージを表示

4.メインプログラム
 4-1. Converterクラスのインスタンスを作成
 4-2. loop構文でユーザーに続行の確認を行い、換算を繰り返す
 4-3. プログラムの終了メッセージを表示

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

# 距離の単位換算を定義するモジュール
module DistanceConverter
  KM_TO_MILES = 0.621371
  MILES_TO_KM = 1.60934

  =begin 【穴埋め問題1】
  ここに、キロメートルをマイルに換算するメソッドを書いてください。
  =end

  =begin 【穴埋め問題2】
  ここに、マイルをキロメートルに換算するメソッドを書いてください。
  =end
end

# 重さの単位換算を定義するモジュール
module WeightConverter
  KG_TO_POUNDS = 2.20462
  POUNDS_TO_KG = 0.453592

  =begin 【穴埋め問題3】
  ここに、キログラムをポンドに換算するメソッドを書いてください。
  =end

  =begin 【穴埋め問題4】
  ここに、ポンドをキログラムに換算するメソッドを書いてください。
  =end
end

# 単位換算を行うクラス
class Converter
  def initialize
    puts "単位換算プログラムを初期化しました。"
  end

  # ユーザーの入力を受け取り、適切な単位換算を行うメソッド
  def perform_conversion
    puts "換算したい単位を選択してください: 1. キロメートルをマイル, 2. マイルをキロメートル, 3. キログラムをポンド, 4. ポンドをキログラム"
    choice = gets.chomp.to_i

    case choice
    when 1
      puts "キロメートルを入力してください:"
      km = gets.to_f
      puts "結果: #{DistanceConverter.km_to_miles(km)} マイル"
    when 2
      puts "マイルを入力してください:"
      miles = gets.to_f
      puts "結果: #{DistanceConverter.miles_to_km(miles)} キロメートル"
    when 3
      puts "キログラムを入力してください:"
      kg = gets.to_f
      puts "結果: #{WeightConverter.kg_to_pounds(kg)} ポンド"
    when 4
      puts "ポンドを入力してください:"
      pounds = gets.to_f
      puts "結果: #{WeightConverter.pounds_to_kg(pounds)} キログラム"
    else
      puts "無効な選択です。もう一度試してください。"
    end
  end
end

# メインプログラム
converter = Converter.new
loop do
  converter.perform_conversion
  puts "続けますか? (y/n)"
  continue = gets.chomp
  break if continue.downcase != 'y'
end
puts "単位換算プログラムを終了します。"

 

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。



解答例と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

********************

# 距離の単位換算を定義するモジュール
module DistanceConverter
  KM_TO_MILES = 0.621371
  MILES_TO_KM = 1.60934

  def self.km_to_miles(km)
    km * KM_TO_MILES
  end

  def self.miles_to_km(miles)
    miles * MILES_TO_KM
  end
end

# 重さの単位換算を定義するモジュール
module WeightConverter
  KG_TO_POUNDS = 2.20462
  POUNDS_TO_KG = 0.453592

  def self.kg_to_pounds(kg)
    kg * KG_TO_POUNDS
  end

  def self.pounds_to_kg(pounds)
    pounds * POUNDS_TO_KG
  end
end

# 単位換算を行うクラス
class Converter
  def initialize
    puts "単位換算プログラムを初期化しました。"
  end

  # ユーザーの入力を受け取り、適切な単位換算を行うメソッド
  def perform_conversion
    puts "換算したい単位を選択してください: 1. キロメートルをマイル, 2. マイルをキロメートル, 3. キログラムをポンド, 4. ポンドをキログラム"
    choice = gets.chomp.to_i

    case choice
    when 1
      puts "キロメートルを入力してください:"
      km = gets.to_f
      puts "結果: #{DistanceConverter.km_to_miles(km)} マイル"
    when 2
      puts "マイルを入力してください:"
      miles = gets.to_f
      puts "結果: #{DistanceConverter.miles_to_km(miles)} キロメートル"
    when 3
      puts "キログラムを入力してください:"
      kg = gets.to_f
      puts "結果: #{WeightConverter.kg_to_pounds(kg)} ポンド"
    when 4
      puts "ポンドを入力してください:"
      pounds = gets.to_f
      puts "結果: #{WeightConverter.pounds_to_kg(pounds)} キログラム"
    else
      puts "無効な選択です。もう一度試してください。"
    end
  end
end

# メインプログラム
converter = Converter.new
loop do
  converter.perform_conversion
  puts "続けますか? (y/n)"
  continue = gets.chomp
  break if continue.downcase != 'y'
end
puts "単位換算プログラムを終了します。"

********************

コードの解説

このプログラムでは、モジュールを使って距離や重さの単位換算を行っています。

モジュールは、クラスとは異なり、インスタンス化できない一方で、メソッドや定数をまとめるための手段として非常に便利です。

モジュールをクラスに組み込むことで、コードの再利用を促進し、共通の機能を効率的に提供できます。

DistanceConverterモジュール

module DistanceConverter
  KM_TO_MILES = 0.621371
  MILES_TO_KM = 1.60934

  def self.km_to_miles(km)
    km * KM_TO_MILES
  end

  def self.miles_to_km(miles)
    miles * MILES_TO_KM
  end
end

DistanceConverterモジュールは、キロメートルとマイルの間の単位換算を行うためのモジュールです。ここでは、定数とメソッドが定義されています。

  • KM_TO_MILES、MILES_TO_KM: 定数は、変換比率を定義しています。例えば、1キロメートルは約0.621マイル、1マイルは約1.609キロメートルです。
  • km_to_milesメソッド: キロメートルをマイルに変換するメソッドです。
  • miles_to_kmメソッド: マイルをキロメートルに変換するメソッドです。

モジュールは、インスタンスを作成せずに、直接モジュール名.メソッド名という形式でメソッドを呼び出せます。これにより、モジュールを介して計算機能を提供しています。

WeightConverterモジュール

module WeightConverter
  KG_TO_POUNDS = 2.20462
  POUNDS_TO_KG = 0.453592

  def self.kg_to_pounds(kg)
    kg * KG_TO_POUNDS
  end

  def self.pounds_to_kg(pounds)
    pounds * POUNDS_TO_KG
  end
end

WeightConverterモジュールは、キログラムとポンドの間の単位換算を行います。モジュールの構造はDistanceConverterと同様ですが、重さの換算を行います。

  • KG_TO_POUNDS、POUNDS_TO_KG: キログラムとポンドの換算比率を定義する定数です。
  • kg_to_poundsメソッド: キログラムをポンドに換算します。
  • pounds_to_kgメソッド: ポンドをキログラムに換算します。

DistanceConverterと同じように、このモジュールのメソッドも、インスタンスを作成せずに直接呼び出すことができます。

Converterクラス

class Converter
  def initialize
    puts "単位換算プログラムを初期化しました。"
  end

  def perform_conversion
    puts "換算したい単位を選択してください..."
    choice = gets.chomp.to_i

    case choice
    when 1
      # キロメートルをマイルに換算
    when 2
      # マイルをキロメートルに換算
    when 3
      # キログラムをポンドに換算
    when 4
      # ポンドをキログラムに換算
    else
      puts "無効な選択です。"
    end
  end
end

Converterクラスは、ユーザーからの入力に基づいて、距離や重さの単位換算を実行します。

  • initializeメソッド: クラスが初期化されるときに実行され、プログラムの初期化メッセージを表示します。
  • perform_conversionメソッド: ユーザーの選択に基づいて、適切なモジュールのメソッドを呼び出し、単位を換算します。case文を使って、選択肢に応じた換算処理を実行します。

モジュールを使う理由

モジュールを使うことで、次のような利点があります。

  1. コードの再利用: 共通の処理をモジュールにまとめることで、他のクラスやプログラムで簡単に再利用できる。
  2. 名前空間の提供: モジュールを使うことで、同じ名前のメソッドや定数が他の部分と衝突することを避けることができる。
  3. 整理されたコード: 機能ごとにモジュールで分けることで、プログラムが見やすく、保守性が向上します。
<<前の問題 問題集Top 次の問題>>

この問題への質問・コメント

この問題を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Ruby練習問題集へ戻る
    トップページへ戻る