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 do 〜 end は「無限ループ」。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 / breakloop do で無限ループを作り、break で抜ける。
メニュー型アプリの基本パターン。
ハンドラメソッドhandle_show_all や handle_add_person のように、
「メニュー1項目分の処理」を1つのメソッドにまとめると、
Main の見通しがよくなる。
select
配列から「条件に合うものだけ」を集めて新しい配列を作る。people.select { |p| p.age < 20 } のように使う。
クラスと配列とメニューの組み合わせ
Person(クラス)で「1人分」を表し、
配列で「複数人」を持ち、
メニューで「どう操作するか」を選べるようにする。
この3つがそろうと、一気に“アプリ感”が増す。
