【初心者向け】Rubyで超簡単ドリンク注文アプリケーション（リファクタリングver）

#@scivola さんよりアドバイスいただき、DRYな部分を整理しました。
こちらの記事は
https://qiita.com/pontarou194/items/9e91b40dcc2da608dd24
の続きです。

もともとは、メソッドが4つありました。。。。

otyaメソッド
coffeeメソッド
beerメソッド
saidaメソッド

これを一つにまとめられました。
もともとはこんな感じ。

#これがメソッドの多いアプリケーション（進化前）

```rb
def otya(otya)
  puts "あなたが選んだのはお茶"
  puts "お茶の値段は100円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * otya
  puts "合計#{total_price}円です"
end

def coffee(coffee)
  puts "あなたが選んだのはコーヒー"
  puts "コーヒーの値段は200円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * coffee
  puts "合計#{total_price}円です"

end

def beer(beer)
  puts "あなたが選んだのはビール"
  puts "ビールの値段は300円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * beer
  puts "合計#{total_price}円です"
end

def saida(saida)
  puts "あなたが選んだのは三ツ矢サイダー"
  puts "サイダーの値段は300円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * saida
  puts "合計#{total_price}円です"
end

otya = 100
coffee = 200
beer = 300
saida = 400

  puts "何を飲みたいですか？"
    drink_menu = ["お茶","コーヒー","ビール","三ツ矢サイダー"]
    drink_menu.each.with_index(1) do |drink_name, number|
      puts "#{number}:#{drink_name}"
    end

  case gets.to_i
    when 1
      otya(otya)
    when 2
      coffee(coffee)
    when 3
      beer(beer)
    when 4
      saida(saida)
    else
      puts "無効な入力値です"
    end
```

#結論、メソッドを一つにまとめると、下記のようなコードとなりました（進化後）

```rb
def order_drink(drink_name, drink_price)
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end

otya = 100
coffee = 200
beer = 300
saida = 400

  puts "何を飲みたいですか？"
    drink_menu = ["お茶","コーヒー","ビール","三ツ矢サイダー"]
    drink_menu.each.with_index(1) do |drink_name, number|
      puts "#{number}:#{drink_name}"
    end

  case gets.to_i
    when 1
      order_drink("お茶", otya)
    when 2
      order_drink("コーヒー", coffee)
    when 3
      order_drink("ビール", beer)
    when 4
      order_drink("三ツ矢サイダー", saida)
    else
      puts "無効な入力値です"
    end
```

@scivola さん完璧です。アドバイスいただきありがとうございました。
なんと、36行もコードを圧縮できました！

@scivola さんがおっしゃるお通り、ポイントは以下の通りです。

・DRYの原則にあてこむ（繰り返しは避ける、似た表現が繰り返される場合もなるべく避ける）
・メソッド名をわかりやすく

↓
（自分で見返したとき用に）もっとわかりやすくします。

擬似コードで書いててわかるように、

```rb
def 
①お茶が選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end

def 
①コーヒーが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end

def 
①ビールが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end

def
①サイダーが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end
```
この①〜③とメソッド名がかなり似ている。
これ、まとめたほうがすっきりしてわかりやすい。

特に
①のあなたが選んだのは○○
→共通化できる

②○○の値段は○○円です
→共通化できる

③合計○○円です
→共通化できる

あとは、いくつ注文しますかとか、gets.to_iとかを一緒に入れて完成。

```rb
def order_drink(drink_name, drink_price)
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end

otya = 100
coffee = 200
beer = 300
saida = 400
```

#引数の使い方について

今回勉強になったポイントは、引数の使い方
複数の引数を使用するケースをあまり経験したことがなかった・・・・・・

なので、いざ自分でコードを組み立てていくとなると、

何がどうなってるのやら？？
っという状況でした。

下記のコードでは、drink_nameが第一引数、drink_priceが第二引数ですね。
コードにポイントをコメントで記述します。

```rb

def order_drink(drink_name, drink_price) #このdrink_nameとdrink_priceが仮引数
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end
```

```rb
  case gets.to_i
    when 1
      order_drink("お茶", otya) #お茶とotyaが実引数
    when 2
      order_drink("コーヒー", coffee) #上記に習って同じ
    when 3
      order_drink("ビール", beer) #上記に習って同じ
    when 4
      order_drink("三ツ矢サイダー", saida) #上記に習って同じ
    else
      puts "無効な入力値です"
    end

```

仮引数と実引数は一致しなくても良いというのがありましたね。なので
これでも下記のようにcase文の実引数をいじって、otya = 100　等の変数宣言を省略することもできます。

```rb

  case gets.to_i
    when 1
      order_drink("お茶", 100)
    when 2
      order_drink("コーヒー", 200)
    when 3
      order_drink("ビール", 300)
    when 4
      order_drink("三ツ矢サイダー", 400)
    else
      puts "無効な入力値です"
    end
```

#メソッド名をわかりやすく。

order_drinkというメソッド名はドリンクをオーダーするためだけなのか、計算もしてくれるのかがわかりずらいですよね。
なので、注文管理メソッドという名前をつけてみました。
グーグル翻訳すると、order_managementとなってましたので、そのまま名付けました。

#最後に、コードをまとめました、こんな感じです。

```rb
def order_management(drink_name, drink_price)
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end

  puts "何を飲みたいですか？"
    drink_menu = ["お茶","コーヒー","ビール","三ツ矢サイダー"]
    drink_menu.each.with_index(1) do |drink_name, number|
      puts "#{number}:#{drink_name}"
    end

  case gets.to_i
    when 1
      order_management("お茶", 100)
    when 2
      order_management("コーヒー", 200)
    when 3
      order_management("ビール", 300)
    when 4
      order_management("三ツ矢サイダー", 400)
    else
      puts "無効な入力値です"
    end

```


引数や変数は便利だなぁと改めて感じました。
また、DRYを原則とすることで、「保守しやすっ！」っと思いました。

ヒアドキュメントはもう少し勉強必要でした、、、

@scivola さんありがとうございました。



@scivola から、さらにアドバイスいただきました。
#二重配列を使用して、case文を省略し、コードを短くできるよう見直しました。

```rb

def order_management(drink_name, drink_price)
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end

  puts "何を飲みたいですか？"
    drink_menu = ["お茶","コーヒー","ビール","三ツ矢サイダー"]
    drink_menu.each.with_index(1) do |drink_name, number|
      puts "#{number}:#{drink_name}"
    end

    drinks = [
      ["お茶", 100],
      ["コーヒー", 200],
      ["ビール", 300],
      ["三ツ矢サイダー", 400]
    ]

    input = gets.to_i
    drink_name = drinks[input - 1][0]
    drink_price = drinks[input -1][1]
  order_management(drink_name, drink_price)
```
（おそらく合っている？
動作は問題なく動きました）

２次元配列について参考とさせていただきました。
https://pikawaka.com/ruby/array

case文使わない方法があるとは・・・・
実際かいてみると、単純構造でした。

#drinks_menuも省略し、配列で処理しました。

```rb

def order_management(drink_name, drink_price)
  puts "あなたが選んだのは#{drink_name}"
  puts "#{drink_name}の値段は#{drink_price}円です"
  puts "いくつ注文しますか？"
  order_quantity = gets.to_i
  total_price = order_quantity * drink_price
  puts "合計#{total_price}円です"
end

drinks = [
  ["お茶", 100],
  ["コーヒー", 200],
  ["ビール", 300],
  ["三ツ矢サイダー", 400]
]

  puts "何を飲みたいですか？"
    drinks.each.with_index(1) do |drink_name, number|
      puts "#{number}:#{drink_name[0]}"
    end

    input = gets.to_i
    drink_name = drinks[input - 1][0]
    drink_price = drinks[input -1][1]
  order_management(drink_name, drink_price)
```

やばい、配列に関する知見が深まりましたｗ
今まで時間がかかっていたものが、5分程で処理できるように・・・・。

@scivola さん、アドバイスいただきありがとうございます。