hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

複雑な条件分岐の実装

複数の条件分岐を書くときはelsifという文法を使う。

1
2
3
4
5
6
7
8
  if 条件式1 then
    # 条件式1が真(true)のときに実行する処理
  elsif 条件式2 then
    # 条件式1が偽(false)のとき、かつ
    # 条件式2が真(true)のときに実行する処理
  else
    # 条件式1と条件式2がどちらとも偽(false)のときに実行する処理
  end

すなわち正か負か0かの条件分岐は以下のようになる。

If


ユーザーから入力された値が'正'、'負'、'0'のどれかを判断するようにする。getsメソッドで得られるユーザーからの入力は文字列であるため、数値オブジェクトに変換しなければならない。
また if 条件式 thenの then は省略することができる。

 to_iメソッド

文字列オブジェクトに対してto_iメソッドを使うとその文字列を数値オブジェクトに変換することができる。

数字以外の文字列オブジェクトは全て0に変換されるので注意。

1
2
3
  string = "30"           # 文字列の30
  number = string.to_i    # 数値の30に変換
  puts number + 20        # => 50が出力
sample.rb
1
2
3
4
5
6
7
8
9
  value = gets.to_i

  if value > 0 then
    puts "値は正です"
  elsif value < 0 then
    puts "値は負です"
  else
    puts "値は0です"
  end

getsメソッドの返り値は「ユーザーが入力した値の文字列オブジェクト」。例えば、単純に数字で17と入力しても返り値は "17" という文字列オブジェクトになる。なので今回のようにgets.to_iと書くことによって、文字列オブジェクトである返り値を数値オブジェクトに変換している。

 

要点チェック

 

メニュー画面の条件分岐

 処理をメソッドとして分離する

ソースコードの量が多くなり、if文の中にも長い処理が書かれているため読みづらくなっている。そこで、複数の処理をメソッドにまとめ、ソースコードを綺麗にする。

コードの量が増え、読みづらくなってきている

 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  if input == 0 then    # 「レビューを書く」
    # 変数の定義
    post = {}
    puts "ジャンルを入力してください:"
    post[:genre]  = gets.chomp
    puts "タイトルを入力してください:"
    post[:title]  = gets.chomp
    puts "感想を入力してください:"
    post[:review] = gets.chomp
    line   = "---------------------------"

    # レビューの描画
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  elsif input == 1 then # 「レビューを読む」
    # レビューを読む
  elsif input == 2 then # 「プログラムを終了する」
    # プログラムを終了させる
  else
    puts "入力された値は無効な値です"
  end

メソッドとは

メソッドとは、ある処理をまとめること。定義したメソッドを呼び出すことで同じ処理を何度も実行することができる。これまでにputsto_sのようなメソッドを使用してきたが、ここでのメソッドは自分で定義するメソッドのことを指す。

メソッドを使うことのメリット

処理をメソッドに分離させることには以下のようなメリットがある。

  • 同じ処理をする場合に何度も同じコードを書かずに済む
  • 修正する場合も定義されたメソッドの処理を修正するのみで済む
  • メソッドに分離することで、コードが分散し管理しやすくなる

同じ処理をする場合に何度も同じコードを書かずに済む

同じ処理を複数回実行したいケースがある。このような時にメソッドを使用しないと、コードをコピーして実行したい箇所に貼り付けることになる。
メソッドを使わずに、1~10までを3回出力したいとすると以下のような記述になる。
同じ記述を3度もすることになるので、冗長に感じます。

【例】メソッドを使わない場合

sample
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
puts "1"
puts "2"
puts "3"
puts "4"
puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"

puts "1"
puts "2"
puts "3"
puts "4"
puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"

puts "1"
puts "2"
puts "3"
puts "4"
puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"

メソッドを利用すれば、以下のように書くことができる。
メソッドを使った方が記述量が少なく、すっきりしている。

【例】メソッドを使った場合

sample.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def number_count
  puts "1"
  puts "2"
  puts "3"
  puts "4"
  puts "5"
  puts "6"
  puts "7"
  puts "8"
  puts "9"
  puts "10"
end

number_count
number_count
number_count

修正する場合も定義されたメソッドの処理を修正するのみで済む

メソッドに処理をまとめておけば、処理の内容が変更になった時も定義元の処理を修正するのみで済む。

例えば、先ほどのプログラムを「5から10までの数字を順番に出力するプログラム」に変更する必要が生じたとする。メソッドを利用していない場合では修正箇所が多くて大変。

【例】メソッドを使わない場合

sample
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"

puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"

puts "5"
puts "6"
puts "7"
puts "8"
puts "9"
puts "10"
メソッドを利用していれば、修正箇所はメソッドの内部だけで済む。

メソッドを使った場合

sample.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def number_count
  puts "5"
  puts "6"
  puts "7"
  puts "8"
  puts "9"
  puts "10"
end

number_count
number_count
number_count

メソッドの定義方法

メソッドを定義するには、以下のように書く。

1
2
3
  def メソッド名
    # 実行する処理
  end

defの横に書いた文字が、メソッド名となる。メソッド名は好きにつけることができるが、小文字の英語から始まり、単語と単語を繋ぐ場合は_で繋ぐ。

メソッドの呼び出し

メソッドを呼び出すときは、メソッド名を記述する。メソッドを呼び出すことで、メソッドの中に記述した処理を実行することができる。

1
2
3
4
5
  def say_hello # メソッドの定義
    puts "Hello World"
  end

  say_hello # メソッドの実行

メソッドの定義部分はそのメソッドが実行されるまで読まれないため注意が必要。上記の例では、1 ~ 3行目までメソッドの定義部分なので始めは読み飛ばされる。5行目でsay_helloを呼び出しているので、ここで初めて定義部分を読み、2行目のputs "Hello World"が実行されることになる。

 

https://tech-master.s3.amazonaws.com/uploads/curriculums//e09b784134aecd25c955a68078fe12e8.png

 

要点チェック

 

メニューで分岐する各処理をメソッドにする

 

メソッド名 処理 入力された値
post_review レビューを書く 0
read_reviews レビューを読む 1
end_program プログラムを終了する 2
exception 無効な値の入力を知らせる それ以外

 

1
2
3
4
5
6
7
  # メソッドの定義
  def post_review
    # 処理
  end

  if input == 0
    post_review # メソッドの呼び出し

 

reviewApp.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  # メソッドの定義
  def post_review
    # 変数の定義
    post = {}
    puts "ジャンルを入力してください:"
    post[:genre]  = gets.chomp
    puts "タイトルを入力してください:"
    post[:title]  = gets.chomp
    puts "感想を入力してください:"
    post[:review] = gets.chomp
    line   = "---------------------------"

    # レビューの描画
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

  def read_reviews
    # レビューを読む
  end

  def end_program
    # プログラムを終了する
  end

  def exception
    puts "入力された値は無効な値です"
  end

  # メニューの表示
  puts "レビュー数:0"
  puts "[0]レビューを書く"
  puts "[1]レビューを読む"
  puts "[2]アプリを終了する"
  input = gets.to_i

  if input == 0 then
    post_review         # post_reviewメソッドの呼び出し
  elsif input == 1 then
    read_reviews        # read_reviewsメソッドの呼び出し
  elsif input == 2 then
    end_program         # end_programメソッドの呼び出し
  else
    exception           # exceptionメソッドの呼び出し
  end

■ 処理の流れ

ここで処理の流れをおさらい。

  • 2行目から29行目
reviewApp.rb
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    def post_review
      # レビューの投稿
    end

    def read_reviews
      # レビューの閲覧
    end

    def end_program
      # プログラムの終了
    end

    def exception
      # エラー処理
    end

まずは、2行目から29行目でこのアプリケーションのメインとなる処理である「レビューの投稿」、「レビューの閲覧」、「プログラムの終了」、「エラー処理」の4つをメソッドとして定義します。

メソッドはどこかで呼び出すことになりますが、このとき呼び出す部分のコードよりも前にメソッドを定義する必要があります。そのため、メソッドはなるべくソースコードの最初に定義するようにしましょう。

  • 32行目から35行目
reviewApp.rb
32
33
34
35
    puts "レビュー数:0"
    puts "[0]レビューを書く"
    puts "[1]レビューを読む"
    puts "[2]アプリを終了する"

メソッドを定義したので、ここからプログラムの処理が始まる。まずはメニューの表示を行う。

  • 36行目
reviewApp.rb
36
     input = gets.to_i

メニューの表示後、メニューの中のどれを実行するか選択するためにターミナルからユーザーに値を入力させる。

getsメソッドで取得した値を変数inputに代入する。入力された値は文字列だが、このあとの比較のときに数字として扱いたいので文字列を数字に変換するto_iメソッドを使う。

  • 38行目から46行目
reviewApp.rb
38
39
40
41
42
43
44
45
46
    if input == 0 then
      post_review
    elsif input == 1 then
      read_reviews
    elsif input == 2 then
      end_program
    else
      exception
    end

ターミナルから入力した値を使って、どの処理を行うのか条件分岐する必要がある。値によって処理を変える条件分岐をプログラムで行うにはif文を使用する。

1
2
3
4
    if input == 0 then
      # inputの値が数字の0のとき
      # この中で何らかの処理を行う
    end

if文で与えられた値によって最初に定義したそれぞれのメソッドの処理を呼び出す。メソッドを呼び出すときにはそのメソッドの名前を記述する。

1
2
3
4
5
    def method1
      # 処理
    end

    method1 # 上で定義したメソッド「method1」を呼び出す

このあとは、getsメソッドで入力した値によって各メソッドが呼び出される。