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

Ruby Ruby
スポンサーリンク

2日目のゴールとテーマ

2日目のテーマは「同じ処理を“部品(メソッド)”にして、何度でも使い回せるようにする」です。
1日目で作った自己紹介アプリは、1人分の自己紹介を作るものでした。

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

同じ処理に名前をつけて「メソッド」にする
メソッドを呼び出して、何人分でも自己紹介を作れるようにする
「コードを短くする」ではなく「意味が分かりやすくなる」ことを体感する

ここを目指します。


「同じことを何度も書く」のがつらくなる瞬間

1人分の自己紹介コードを思い出す

昨日のコードは、ざっくりこんな流れでした。

名前を聞く
年齢を聞く
趣味を聞く
年齢に応じてコメントを決める
自己紹介文を表示する

もし「2人分の自己紹介を作りたい」となったら、
同じようなコードをもう1セットコピペすることになります。

それでも動きますが、こういう問題が出てきます。

修正したいときに、2か所直さないといけない
3人、4人と増えると、コードがどんどん長くなる
「どこが何をしているのか」が分かりにくくなる

ここで登場するのが「メソッド」です。


メソッドとは何かをイメージでつかむ

「名前のついた処理のかたまり」

メソッドは、簡単に言うと

「この処理に名前をつけて、あとから何度でも呼び出せるようにしたもの」

です。

例えば、

「自己紹介を1人分作って表示する」という処理に
introduce という名前をつけておく

そうすると、メインの流れは

introduce
introduce
Ruby

のように書けます。

中身がどれだけ長くても、
呼び出す側は「自己紹介をする」という意味だけを意識すればよくなります。


Rubyのメソッドの基本形

def 〜 end で囲む

Rubyでメソッドを定義する基本形はこうです。

def メソッド名
  # ここにやりたい処理を書く
end
Ruby

例えば、単純に挨拶するメソッドならこうです。

def hello
  puts "こんにちは!"
end

hello
hello
Ruby

これを実行すると、

こんにちは!
こんにちは!

と2回表示されます。

ここでのポイントは、

def hello で「hello という名前のメソッド」を定義している
end までがそのメソッドの中身
hello と書くだけで、その中身が実行される

という流れです。


自己紹介処理をメソッドにまとめる

まずは「1人分の自己紹介」をメソッドにする

昨日の自己紹介処理を、丸ごとメソッドにしてみます。

def introduce
  puts "あなたの名前を教えてください:"
  name = gets.chomp

  puts "あなたの年齢を教えてください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "あなたの好きなこと(趣味)を教えてください:"
  hobby = gets.chomp

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

  puts "------------------------"
  puts "自己紹介文:"
  puts "はじめまして、#{name}です。"
  puts "年齢は#{age}歳です。#{age_comment}"
  puts "好きなことは#{hobby}です。"
  puts "よろしくお願いします!"
end
Ruby

そして、メイン部分はこうなります。

introduce
Ruby

これだけで、1人分の自己紹介が動きます。

2人分、3人分を一瞬で増やせる

同じメソッドを何度も呼べば、
その回数分だけ自己紹介が行われます。

puts "1人目の自己紹介です。"
introduce

puts "2人目の自己紹介です。"
introduce
Ruby

これで、コードの重複なしに「2人分の自己紹介」ができます。

ここで感じてほしいのは、

「処理の中身をコピペする」のではなく
「処理の名前を呼ぶ」だけで済む気持ちよさ

です。


メソッドに「入力」と「出力」を持たせる

introduceの結果を“返す”形にしてみる

今の introduce は、自己紹介文を画面に表示して終わりです。
これでもいいのですが、もう一歩進めて、

「自己紹介文を文字列として返すメソッド」

にしてみましょう。

def build_introduction
  puts "あなたの名前を教えてください:"
  name = gets.chomp

  puts "あなたの年齢を教えてください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "あなたの好きなこと(趣味)を教えてください:"
  hobby = gets.chomp

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

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

  return intro
end
Ruby

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

intro = "" で空の文字列を用意している
intro += "..." で、1行ずつ文字列を足している
\n は「改行」を表す特殊文字
最後に return intro で、その文字列をメソッドの“結果”として返している

Rubyでは、return を書かなくても「最後に評価された値」が戻り値になりますが、
初心者のうちは return を書いておいた方が分かりやすいです。

戻り値を受け取ってから表示する

このメソッドを使う側は、こう書きます。

intro_text = build_introduction

puts "------------------------"
puts "自己紹介文:"
puts intro_text
Ruby

これで、

入力を受け取って自己紹介文を組み立てる → build_introduction
画面に表示する → puts

という役割分担ができます。


引数つきメソッドのイメージをつかむ

「渡された値を使って処理する」メソッド

今度は逆に、「外から値を渡して、それを使って処理する」メソッドを考えます。

例えば、「年齢からコメントを決める」部分だけをメソッドにしてみましょう。

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

ここでのポイントは、

def build_age_comment(age)(age) が「引数」
メソッドの中では、その age を普通の変数のように使える
最後に評価された文字列が、そのまま戻り値になる

ということです。

build_introductionの中で使ってみる

さっきの build_introduction を、
このメソッドを使う形に書き換えます。

def build_introduction
  puts "あなたの名前を教えてください:"
  name = gets.chomp

  puts "あなたの年齢を教えてください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "あなたの好きなこと(趣味)を教えてください:"
  hobby = gets.chomp

  age_comment = build_age_comment(age)

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

  return intro
end
Ruby

こうすると、

「年齢コメントのロジック」は build_age_comment に閉じ込められる
build_introduction は「入力を集めて、文章を組み立てる」ことに集中できる

という状態になります。


2日目のミニアプリ:「複数人の自己紹介をまとめて作る」

人数を聞いて、その回数だけ自己紹介を作る

ここまで来たら、
「何人分の自己紹介を作るか」をユーザーに決めてもらいましょう。

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

def build_introduction
  puts "あなたの名前を教えてください:"
  name = gets.chomp

  puts "あなたの年齢を教えてください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "あなたの好きなこと(趣味)を教えてください:"
  hobby = gets.chomp

  age_comment = build_age_comment(age)

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

  return intro
end

puts "何人分の自己紹介を作りますか?"
count_text = gets.chomp
count = count_text.to_i

i = 1
while i <= count
  puts "========================"
  puts "#{i}人目の自己紹介です。"

  intro_text = build_introduction

  puts "------------------------"
  puts "自己紹介文:"
  puts intro_text

  i += 1
end
Ruby

ここで新しく出てきたのは while です。

while 条件end の間の処理を、条件が true の間繰り返す

この例では、

i = 1 からスタート
i <= count の間、自己紹介を繰り返す
最後に i += 1 で i を1ずつ増やす

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


2日目のまとめ

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

メソッド(def 〜 end)
処理のかたまりに名前をつけて、何度でも呼び出せるようにする。

戻り値(return)
メソッドが「結果として返す値」。
return 値 で明示的に返すか、最後に評価された式がそのまま戻り値になる。

引数
def foo(x, y)(x, y) の部分。
呼び出し側から値を渡して、メソッドの中で使えるようにする。

処理の分割
「年齢コメントを決める」「自己紹介文を組み立てる」を別メソッドにすることで、
1つ1つのメソッドの役割がはっきりする。

繰り返し(while)
while 条件 で、条件が成り立つ間、同じ処理を繰り返す。
カウンタ変数(i)を使って回数を制御する。


次回(3日目)への予告

3日目は、今日の「複数人の自己紹介」をもう一歩進めて、

自己紹介文を配列にためておく
あとからまとめて一覧表示する
「データを集めて、あとで使う」という感覚を身につける

という方向に進みます。

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