某プログラミング教室　Ruby 基礎　応用機能

#レビュー表示システムの応用機能
　某プログラミング教室のカリキュラムを復習してる際に応用機能の実装が推奨されていたので試しにやってみました。
　***注意***
・あくまで実装例です！より効率の良い実装方法や別の回答はたくさんあります。
・かなり基本的なカリキュラムなので応用という意味が皆さんの想像とは違っています。あくまでカリキュラム内に答えがない拡張機能ということです。

#早速回答例を
###1.メニュー表示を別関数として定義
 予め使っていたレビュー表示の部分(putsで表示していた部分)を、新たな関数内に貼り付けます。
 このとき仮引数を用意すること、呼び出し元でshow("ハッシュ名")で実引数を渡す記述をすることを忘れないように。

```review.rb
def show(review)
  line = "------------------------------------"
  puts"ジャンル:#{review[:genle]}\n#{line}"
  puts"タイトル:#{review[:title]}\n#{line}"
  puts"感想:\n#{review[:text]}\n#{line}"
  puts"採点:#{review[:point]}\n#{line}"
end
```
###2.新しいレビュー項目を増やす
　これは、レビューを投稿する関数内で新たに入力項目(puts)を増やし、getsで入力待ちにして、入力された値をハッシュに代入するだけです。
　ちなみに、レビュー表示のために新たにputsを増やす必要があるので、***1***の「表示を別関数にする処理」作業を先にした方が効率的です。

```review.rb
def write(hairetu)
  post = {}
  puts "ジャンルを入力してください:"
~~~省略~~~
  puts "100点満点で評価をしてください:"
  point = gets.to_i
  while point > 100
    puts"0~100の数値を入力してください"
    point = gets.to_i
  end
  post[:point] = point
~~~省略~~~
```
***(入力した値を.to_iで数値にしているので「.chomp」を付けない、表示する際も\nを無駄に付けて改行しないように気をつける)***
(今回は採点項目というめんどくさいやつを追加したのでこのような書き方ですが、普通の文字列であれば他の項目と同様の書き方ができます。)

###３.レビューが1つも書かれていないときに「レビューを読む」は選べなくする
 「&& box.length > 0」の記述によって、レビュー（ハッシュ）が入っている配列の中身が0以上の数出ない限りread関数（レビューを読むための関数)を呼べないことにできます。

```review.rb
while true
  puts "レビュー数:#{box.length}"
  puts"[0]レビューを書く"
  puts"[1]レビューを読む"
  puts"[2]アプリを終了する"
  if choice==0
~~~省略~~~
  elsif choice==1 && box.length > 0
    read(box)
~~~省略~~~
end
```

###４.入力された見たいレビューの番号が、レビュー数より大きい場合に再入力させる
```review.rb
  puts "見たいレビューの番号を入力してください:"
  choice = gets.to_i
  while choice > box.length 
    puts "既存のレビューの番号を入力してください:"
    choice = gets.to_i
  end
```
このような書き方をすることで,ユーザーが入力した数値が配列boxの中の要素数よりも大きいならば値を再入力させ続けるwhileメソッドを設置できます。
***ちなみに***
 この記述では、ユーザーが0や文字列を入力した際に最近投稿したレビューが表示されてしまいます。いろいろ解決策はありますが、一番シンプルな方法が、

```review.rb
  if choice == 0
    puts "無効な値です"
    return 
  else
~~~while文以降の処理~~~
end
```
というifの条件文で処理を囲ってしまう方法です。
試してみたところ、0も文字列もしっかりはじきます。
returnの後にputsを置いたら無言でread関数が終了するのでご注意を。
また、esle分をしっかり書かないと同じように無言で終了するのでご注意を。

#サンプルコード
```review.rb
box = []
def write(hairetu)
  post = {}
  puts "ジャンルを入力してください:"
  post[:genle] = gets.chomp
  puts "タイトルを入力してください:"
  post[:title] = gets.chomp
  puts "感想を入力してください:"
  post[:text] = gets.chomp
  puts "100点満点で評価をしてください:"
  point = gets.to_i
  while point > 100
    puts"0~100の数値を入力してください"
    point = gets.to_i
  end
  post[:point] = point
  show(post)
  hairetu << post
  return hairetu
end

def read(box)

  box.each_with_index do |reviews,index|
    index += 1
    puts "#{[index]}:#{reviews[:title]}のレビュー"
  end
  puts "見たいレビューの番号を入力してください:"
  choice = gets.to_i
  if choice == 0
    puts "無効な値です"
    return 
  else
  while choice > box.length 
    puts "既存のレビューの番号を入力してください:"
    choice = gets.to_i
  end
  choice -= 1
  review = box[choice]
  show(review)
end
end

def show(review)
  line = "------------------------------------"
  puts"ジャンル:#{review[:genle]}\n#{line}"
  puts"タイトル:#{review[:title]}\n#{line}"
  puts"感想:\n#{review[:text]}\n#{line}"
  puts"採点:#{review[:point]}\n#{line}"
end

def exit
  exit
end

def error
  puts "無効な値です"
end

while true
  puts "レビュー数:#{box.length}"
  puts"[0]レビューを書く"
  puts"[1]レビューを読む"
  puts"[2]アプリを終了する"
  choice = gets.to_i
  if choice==0
    box = write(box)
  elsif choice==1 && box.length > 0
    read(box)
  elsif choice==2
    exit
  else
    error
  end
end
```
正直まだエラーが出る可能性がいくらでもあるので何か欠点を見つけられた際にはコメントしていただけると喜びます。