hiyoko-programingの日記

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

レビューアプリの完成ソースコード

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
47
48
49
50
51
52
53
54
55
56
# メソッドの定義
  def post_review(a_posts)
    # 変数の定義
    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}"

    # 配列オブジェクトに追加
    a_posts << post

    # a_postsをメソッドの呼び出し元に返す
    return a_posts
  end

  def read_reviews
    # レビューを読む
  end

  def end_program
    exit
  end

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

  posts = []             # 配列オブジェクトpostsの生成

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

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

■ 処理の流れ

おさらい。

  • 2行目から35行目
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

いままで通りメソッドの定義する。今回post_reviewメソッドだけ大幅に処理の内容が変わった。

  • 37行目
reviewApp.rb
37
    posts = []

レビューの内容を保存するための配列オブジェクトpostsを定義する。
ここでポイントとなるのは定義する場所。各メソッドの中でも、while文の中でも、while文のあとでもない。

  • 各メソッドの中で定義すると、使えるのがそのメソッドの中のみになってしまいう。今回は様々なメソッドやその外側で使用したいので各メソッドの中では定義しない。

  • while文の中で定義すると繰り返すたびに配列が初期化(最初の何も入っていない状態)されてしまうため、while文の中でも定義できない。

    37
    38
    39
    40
      while true do
        posts = [] # 繰り返す度に配列オブジェクトが初期化される
        # 処理
      end
    
  • while文のあとだと、そもそもすべての処理が終わっているので定義しても意味がない。

そこで、定義するのは各メソッド内ではなく、かつwhile文のブロックより前

reviewApp.rb
31
32
33
34
35
36
37
38
39
40
41
    # 省略

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

    posts = []

    while true do

    # 省略
  • 39行目から56行目

基本的な処理は変わらない。
「メニューの表示」 → 「ターミナルからの入力」 → 「入力に応じた処理」
という流れをwhile文の中で繰り返している。

ただし、メニューで「【0】レビューを書く」を選択したときだけ処理が変わる。

  • 47行目から48行目
reviewApp.rb
47
48
    if input == 0 then
      posts = post_review(posts)

メニューで「【0】レビューを書く」を選択すると条件分岐によって48行目のpost_reviewメソッドの呼び出しが行われる。このとき引数で配列オブジェクトの変数postsをpost_reviewメソッドに渡す。

reviewApp.rb
48
    posts = post_review(posts) # postsを引数としてpost_reviewメソッドに渡す

引数として渡された配列オブジェクトpostsはpost_reviewメソッドの変数に代入される。

  • 2行目

再び、2行目に処理が戻る。定義したpost_reviewメソッドが呼ばれたため。

reviewApp.rb
2
    def post_review(a_posts)

post_reviewメソッドは引数を受け取る。48行目でこのpost_reviewメソッドが呼ばれたときに引数として変数postsが渡された。この変数postsの中にはレビューを管理するための配列オブジェクトが入っている。

引数として渡された変数postsの中に入っていた、レビューを管理するための配列オブジェクトはpost_reviewメソッドの変数a_postsに代入され、メソッド内で使用できるようになる。

  • 48行目

    reviewApp.rb
    48
      posts = post_review(posts) # postsを引数としてpost_reviewメソッドに渡す
    
  • 2行目

    reviewApp.rb
    2
    3
      def post_review(a_posts) # 渡されたpostsの中の配列オブジェクトが変数a_postsに代入される
        # 変数a_postsとして、引数の配列オブジェクトをメソッド内で使える
    
    • 4行目から16行目

4行目から16行目では今までと同様にレビューの情報を持つハッシュオブジェクトを生成し、ターミナルからレビューを入力させる処理を行う。また、入力が終わったレビュー情報をターミナルに表示させる。

  • 19行目
reviewApp.rb
19
    a_posts << post

19行目では、生成したレビューのハッシュオブジェクトpostを引数で受け取った配列オブジェクトa_postsに追加する。これで配列a_postsの最後にいま入力したレビューのハッシュオブジェクトが入る。図で表すと、以下のようになる。

配列にハッシュを追加する

  • 22行目
reviewApp.rb
22
    return a_posts

変数a_postsには入力したレビューのハッシュオブジェクトが新しく追加された配列オブジェクトが入っている。これをメソッドの呼び出し元に返してあげる。メソッドの最後で、メソッドの呼び出し元に値を返すときにはreturnを使う。

22
    return メソッドの呼び出し元に返す値

今回は新しく書いたレビューを追加した配列オブジェクトであるa_postsをreturnで返すようにする。このreturnで返す値を返り値という。

  • 48行目

メソッド内の処理がすべて終わると、プログラムではメソッドを呼び出した部分に処理が戻る。post_reviewメソッドを呼び出したのは48行目。

reviewApp.rb
48
    posts = post_review(posts)

post_reviewメソッドは返り値を返すので、変数postsにはその返り値が代入される。

reviewApp.rb
48
    posts = post_reviewの返り値

post_reviewメソッドの返り値は、新しく書いたレビューを追加した配列オブジェクト。この配列オブジェクトは元は変数postsに代入されていたものなので、結果としてpostsには新しく書いたレビューが1つ追加された配列オブジェクトが代入されることになる。

具体的な例として、すでに「るろうに剣心」と「君に届け」のレビューを書いたあとの状態で、新しく「アバター」のレビューを書く処理の流れを追ってみる。

最初の段階では配列オブジェクトの変数postsには「るろうに剣心」と「君に届け」のレビューのハッシュオブジェクトが入っている。

  • post_reviewメソッドの呼び出し

    reviewApp.rb
    47
    48
      # 元のpostsには「るろうに剣心」と「君に届け」のレビューのハッシュオブジェクトが入っていた
      posts = post_review(posts)
    
  • post_reviewメソッド

    reviewApp.rb
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
      def post_review(a_posts)
        # a_postsは「るろうに剣心」と「君に届け」の入っている配列オブジェクト
        # (48行目で引数として渡された変数postsに代入されていた配列オブジェクト)
    
        # 新たに「アバター」のレビューを投稿
    
        # 「アバター」のレビューを配列オブジェクトに追加
        a_posts << post
    
        # メソッドの呼び出し元に新しく書いたレビューを追加した配列オブジェクトを返す
        return a_posts
    
  • post_reviewメソッドの返り値を代入

    reviewApp.rb
    48
    49
    50
      posts = post_review(posts)
      # 「アバター」のレビューが新しく追加された配列オブジェクトを変数postsに代入
      # postsには「るろうに剣心」と「君に届け」と「アバター」のレビュー情報が入った
    

ハッシュオブジェクトの追加

こうして、結果として変数postsに新しくレビューのハッシュオブジェクトを追加することができた。