前提・実現したいこと
初めまして。ruby 初学者です。
ただいま、補足情報にあります、TDD Boot Camp 大阪様の
「自動販売機のプログラム」を実装中です。
※詳細を補足情報に記載しております
補足情報の「ステップ3」までは一度実装したのですが、
現在、「新規の飲み物を追加する(コードの[在庫管理]部分です)」というところでつまづいております。
自動販売機で飲み物を購入する際、
「drink_stock」メソッドにて、「has_key?」を使って、
ドリンク名の確認を行い、ドリンク名が見つからない場合に
ドリンクのストックを実行できしたいと考えているのですが、
そもそも「drink_stock」の値が取れないという状況です。
ぜひアドバイスをいただければ幸いです。
何卒宜しくお願い申し上げます。
発生している問題・エラーメッセージ
irb(main):101:0> v = VendingMachine.new => #<VendingMachine:0x00007fb21d13d7c0 @total=0, @sale_amount=0, @drink_table=[{:name=>:cola, :price=>120, :stock=>5}]> irb(main):102:0> v.drink_stock(cola) Traceback (most recent call last): 4: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/bin/irb:23:in `<main>' 3: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/bin/irb:23:in `load' 2: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 1: from (irb):102 NameError (undefined local variable or method `cola' for main:Object) irb(main):103:0> v.drink_stock(:cola) Traceback (most recent call last): 6: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/bin/irb:23:in `<main>' 5: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/bin/irb:23:in `load' 4: from /Users/tsukinokikatsuhiro/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 3: from (irb):103 2: from (irb):103:in `rescue in irb_binding' 1: from (irb):64:in `drink_stock' NoMethodError (undefined method `has_key?' for [{:name=>:cola, :price=>120, :stock=>5}]:Array)
該当のソースコード
class Drink attr_reader :name,:price def initialize(name, price) @name = name @price = price end def self.cola self.new(:cola,120) end def self.redbull self.new(:redbull,200) end def self.water self.new(:water,100) end end class VendingMachine AVAILABLE_MONEY = [10, 50, 100, 500, 1000].freeze # これで投入合計額、売上金額をメソッドで呼び出せる。 attr_accessor :total, :sale_amount # :drink_table #初期値 def initialize @total = 0 @sale_amount = 0 @drink_table = [] @drink_table << {name: :cola, price:120, stock:5} # v1.drink_table[0][:stock]で確認できる end def drink_table @drink_table end #お金を受け取る 繰り返し def insert(money) if VendingMachine::AVAILABLE_MONEY.include?(money) @total += money else puts "#{money}円は使えません" end end #払い戻し def refund if @total == 0 puts "払い戻すお金はありません" else puts "#{@total}円を払い戻し" @total = 0 end end # 在庫管理 def drink_stock(drink) unless @drink_table.has_key?(Drink.name) @drink_table << { name: drink.name, price: drink.price, stock: 5 } end @drink_table end #購入可能ドリンクの表示 def purchasable @purchasable end #選んだドリンク以上のお金が入ってるか? def money_check @total >= drink_table[:price] end def purchase #購入したいドリンクをドリンク名で選んでもらう。 #購入可能ドリンクの表示 if money_check && stock # total金額から購入する(選択した)ドリンクの料金を引く @total -= drink_table[:price] # 選んだドリンクのストックを1本減らす @drink_table[:stock] -= 1 # 選んだドリンクの料金分売り上げが増える @sale_amount += drink_table[:price] # puts "残りは、#{@drink_table[:stock]}本です" else puts "購入できません" end end end
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
引用:http://devtesting.jp/tddbc/?TDDBC%E5%A4%A7%E9%98%AA3.0%2F%E8%AA%B2%E9%A1%8C
<プログラムの実装手順>
●【ステップ0 お金の投入と払い戻し】
10円玉、50円玉、100円玉、500円玉、1000円札を1つずつ投入できる。
投入は複数回できる。
投入金額の総計を取得できる。
払い戻し操作を行うと、投入金額の総計を釣り銭として出力する。
ステップ1 扱えないお金
想定外のもの(硬貨:1円玉、5円玉。お札:千円札以外のお札)が投入された場合は、投入金額に加算せず、それをそのまま釣り銭としてユーザに出力する。
●【ステップ2 ジュースの管理】
値段と名前の属性からなるジュースを1種類格納できる。初期状態で、コーラ(値段:120円、名前”コーラ”)を5本格納している。
格納されているジュースの情報(値段と名前と在庫)を取得できる。
注意:責務を持ちすぎていませんか?責任を持ちすぎていたら分割しましょう
●【ステップ3 購入】
投入金額、在庫の点で、コーラが購入できるかどうかを取得できる。
ジュース値段以上の投入金額が投入されている条件下で購入操作を行うと、ジュースの在庫を減らし、売り上げ金額を増やす。
投入金額が足りない場合もしくは在庫がない場合、購入操作を行っても何もしない。
現在の売上金額を取得できる。
払い戻し操作では現在の投入金額からジュース購入金額を引いた釣り銭を出力する。
注意:責務が集中していませんか?責務が多すぎると思ったら分けてみましょう
●【ステップ4 機能拡張】
ジュースを3種類管理できるようにする。
在庫にレッドブル(値段:200円、名前”レッドブル”)5本を追加する。
在庫に水(値段:100円、名前”水”)5本を追加する。
投入金額、在庫の点で購入可能なドリンクのリストを取得できる。
●【ステップ5 釣り銭と売り上げ管理】
ジュース値段以上の投入金額が投入されている条件下で購入操作を行うと、釣り銭(投入金額とジュース値段の差分)を出力する。
ジュースと投入金額が同じ場合、つまり、釣り銭0円の場合も、釣り銭0円と出力する。
釣り銭の硬貨の種類は考慮しなくてよい。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/19 10:43 編集