@scivola さんよりアドバイスいただき、DRYな部分を整理しました。
こちらの記事は
https://qiita.com/pontarou194/items/9e91b40dcc2da608dd24
の続きです。
もともとは、メソッドが4つありました。。。。
otyaメソッド
coffeeメソッド
beerメソッド
saidaメソッド
これを一つにまとめられました。
もともとはこんな感じ。
これがメソッドの多いアプリケーション(進化前)
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
結論、メソッドを一つにまとめると、下記のようなコードとなりました(進化後)
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の原則にあてこむ(繰り返しは避ける、似た表現が繰り返される場合もなるべく避ける)
・メソッド名をわかりやすく
↓
(自分で見返したとき用に)もっとわかりやすくします。
擬似コードで書いててわかるように、
def
①お茶が選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end
def
①コーヒーが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end
def
①ビールが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end
def
①サイダーが選ばれた場合、値段を表示
②注文数を入力
③合計額を表示
end
この①〜③とメソッド名がかなり似ている。
これ、まとめたほうがすっきりしてわかりやすい。
特に
①のあなたが選んだのは○○
→共通化できる
②○○の値段は○○円です
→共通化できる
③合計○○円です
→共通化できる
あとは、いくつ注文しますかとか、gets.to_iとかを一緒に入れて完成。
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が第二引数ですね。
コードにポイントをコメントで記述します。
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
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 等の変数宣言を省略することもできます。
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となってましたので、そのまま名付けました。
最後に、コードをまとめました、こんな感じです。
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文を省略し、コードを短くできるよう見直しました。
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)
(おそらく合っている?
動作は問題なく動きました)
2次元配列について参考とさせていただきました。
https://pikawaka.com/ruby/array
case文使わない方法があるとは・・・・
実際かいてみると、単純構造でした。
drinks_menuも省略し、配列で処理しました。
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)
やばい、配列に関する知見が深まりましたw
今まで時間がかかっていたものが、5分程で処理できるように・・・・。
@scivola さん、アドバイスいただきありがとうございます。