Ruby | 2週間で身につく、アプリを作りながら学ぶRubyの基本 - 6日目

Ruby Ruby
スポンサーリンク

6日目のゴールとテーマ

6日目のテーマは「Personクラスを“アプリっぽく”動かす:メニューで操作できる名簿アプリ」です。
5日目で「Person という型」を作り、person.introduction のように扱えるようになりました。

今日はそこから一歩進めて、

メニューを表示して、やりたい操作を選べるようにする
Person の配列を「名簿」として扱う
追加・一覧表示・条件付き表示をメニューから呼び出す

という、「小さなコンソールアプリ」の形に近づけていきます。


アプリに“メニュー”があると何がうれしいか

「1回動いて終わり」から「何度でも操作できる」へ

今までのコードは、
「人数を聞く → 入力する → 一覧表示して終わり」という一方通行でした。

でも、実際のアプリは、

あとから人を追加したい
今の名簿をもう一度見たい
条件を変えて表示したい

といった操作を、何度も繰り返します。

そこで必要になるのが「メニュー」です。

メニューを出して、
「1: 全員を表示」「2: 新しく追加」「3: 20歳未満だけ表示」「0: 終了」
のように選べるようにすると、一気に“アプリ感”が出てきます。


まずはPersonクラスをもう一度整理する

6日目で使うPersonクラス

今日のコードの土台になる Person クラスを、改めてまとめておきます。

class Person
  attr_accessor :name, :age, :hobby

  def initialize(name, age, hobby)
    @name = name
    @age = age
    @hobby = hobby
  end

  def age_comment
    if @age <= 0
      "年齢はひみつなんですね。"
    elsif @age < 20
      "とても若いですね!"
    elsif @age < 40
      "働き盛りの世代ですね。"
    else
      "人生経験が豊富そうですね。"
    end
  end

  def introduction
    text = ""
    text += "はじめまして、#{@name}です。\n"
    text += "年齢は#{@age}歳です。#{age_comment}\n"
    text += "好きなことは#{@hobby}です。\n"
    text += "よろしくお願いします!\n"
    text
  end
end
Ruby

ここでの重要ポイントは、Person が

名前・年齢・趣味という「データ」
年齢コメントと自己紹介文という「振る舞い」

を両方持っていることです。


入力からPersonを作る“部品”を用意する

入力専用のメソッドを作る

メニューから何度も「新しい人を追加する」ことになるので、
入力部分はメソッドにしておきます。

def build_person_from_input
  puts "名前を入力してください:"
  name = gets.chomp

  puts "年齢を入力してください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "好きなこと(趣味)を入力してください:"
  hobby = gets.chomp

  Person.new(name, age, hobby)
end
Ruby

ここでのポイントは、戻り値として Person.new(...) をそのまま返していることです。
Rubyでは、メソッドの最後に書かれた式の値が、そのまま戻り値になります。


メニューを表示して選択を受け取る

メニュー表示と入力を分けて考える

まずは「メニューを表示する」部分をメソッドにします。

def show_menu
  puts "========================"
  puts "名簿アプリ メニュー"
  puts "1: 全員の自己紹介を表示"
  puts "2: 新しい人を追加"
  puts "3: 20歳未満の人だけ表示"
  puts "0: 終了"
  puts "番号を入力してください:"
end
Ruby

次に、「番号を読み取って整数にする」部分もメソッドにします。

def read_menu_number
  input = gets.chomp
  input.to_i
end
Ruby

ここではあえてエラーチェックをシンプルにしておきます。
(「数字以外が入ったらどうするか」は、7日目以降で強化していくイメージです)


メインループを作る:whileでメニューを繰り返す

「0が選ばれるまでメニューを出し続ける」

アプリの中心になるのは、この「メインループ」です。

people = []

loop do
  show_menu
  choice = read_menu_number

  if choice == 0
    puts "アプリを終了します。"
    break
  elsif choice == 1
    handle_show_all(people)
  elsif choice == 2
    handle_add_person(people)
  elsif choice == 3
    handle_show_under_20(people)
  else
    puts "不正な番号です。もう一度入力してください。"
  end
end
Ruby

ここでの重要ポイントを深掘りします。

people = [] は「Person の配列(名簿)」を表す
loop doend は「無限ループ」。break で抜ける
choice が 0 のときだけ break して終了
それ以外の番号は、それぞれの処理用メソッド(handle_〜)に任せる

この形は、コンソールアプリの「基本パターン」です。
メインループは「メニューを出す」「選択を受け取る」「処理を振り分ける」だけにして、
中身の処理は別メソッドに分けると読みやすくなります。


メニューごとの処理をメソッドに分ける

1: 全員の自己紹介を表示する

def handle_show_all(people)
  if people.empty?
    puts "まだ登録されている人がいません。"
    return
  end

  puts "========================"
  puts "全員の自己紹介を表示します。"

  people.each_with_index do |person, idx|
    puts "------------------------"
    puts "#{idx + 1}人目:"
    puts person.introduction
  end
end
Ruby

ここでのポイントは、

配列が空かどうかを people.empty? でチェックしている
空ならメッセージを出して return で早めに抜ける
each_with_index で「何人目か」を表示しながら回している
自己紹介文は person.introduction に任せている

ということです。

2: 新しい人を追加する

def handle_add_person(people)
  puts "新しい人の情報を入力します。"

  person = build_person_from_input
  people << person

  puts "登録しました。"
end
Ruby

ここでは、

入力専用メソッド build_person_from_input を再利用している
作った Person を people << person で名簿に追加している

という流れになっています。

3: 20歳未満の人だけ表示する

def handle_show_under_20(people)
  puts "20歳未満の人の自己紹介を表示します。"

  young_people = people.select { |person| person.age < 20 }

  if young_people.empty?
    puts "20歳未満の人は登録されていません。"
    return
  end

  young_people.each_with_index do |person, idx|
    puts "------------------------"
    puts "#{idx + 1}人目:"
    puts person.introduction
  end
end
Ruby

ここで新しく出てきたのが select です。

people.select { |person| 条件 } は、
「条件が true になる要素だけを集めた新しい配列」を返します。

この例では、

person.age < 20 の人だけを集めて young_people にしている
若い人がいなければメッセージを出して return
いれば、その人たちだけ自己紹介を表示

という流れになっています。


「配列 × クラス × メニュー」がそろった状態を眺める

ここまででできていること

6日目の時点で、あなたのアプリはすでにこんなことができています。

Person という「人の型」を自分で定義している
Person の配列を「名簿」として扱っている
メニューから操作を選べる
新しい人を追加できる
全員分の自己紹介をいつでも表示できる
条件(20歳未満)で絞り込んで表示できる

これはもう、「学習用のサンプル」を超えて、
小さいながらもちゃんとした“アプリ”の形になっています。


6日目のまとめ

今日のキーワードを整理します。

メニュー構造
メニューを表示するメソッド(show_menu)
番号を読むメソッド(read_menu_number)
メインループで「選択 → 処理の振り分け」を行う。

loop do / break
loop do で無限ループを作り、
break で抜ける。
メニュー型アプリの基本パターン。

ハンドラメソッド
handle_show_allhandle_add_person のように、
「メニュー1項目分の処理」を1つのメソッドにまとめると、
Main の見通しがよくなる。

select
配列から「条件に合うものだけ」を集めて新しい配列を作る。
people.select { |p| p.age < 20 } のように使う。

クラスと配列とメニューの組み合わせ
Person(クラス)で「1人分」を表し、
配列で「複数人」を持ち、
メニューで「どう操作するか」を選べるようにする。
この3つがそろうと、一気に“アプリ感”が増す。

タイトルとURLをコピーしました