Menu
Coddy logo textTech

復習 - 自動販売機

CoddyのRubyジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 21/57。

challenge icon

チャレンジ

中級

UnknownProduct、SoldOut、NotEnoughCreditというエラークラスを持つ自動販売機を作成してください。これらはすべてStandardErrorのサブクラスです。VendingMachine.new(stock)はハッシュ{ "cola" => [150, 2] }(価格はセント単位、個数)を受け取ります。creditは読み取り可能ですが、設定できるのはプライベートセッター経由のみです。insert(cents)はクレジットを加算します。buy(name)は、順にUnknownProduct(no such product: tea)、SoldOut(cola is sold out)、またはNotEnoughCredit(cola costs 1.50, credit 1.00)を発生させます。それ以外の場合は在庫から商品を1つ取り出し、価格を差し引いて、名前を返します。refundはクレジットを返し、その値を0に設定します。プライベートヘルパーmoney(cents)は1.50の形式に整えます。

提供されたコードは、最初の行(cola:150:2,chips:90:1)から在庫を読み込み、その後にコマンドinsert n、buy name、またはrefundを読み込みます。credit 2.00、bought cola、refund 0.50、またはエラーメッセージを出力し、最後に外部からcreditを設定しようとして、credit is protectedを出力します。

コードはunknown_product.rb、sold_out.rb、not_enough_credit.rb、vending_machine.rbに記述します。main.rbには提供された入出力コードが含まれており、編集できません。

自分で試してみよう

require_relative 'unknown_product'
require_relative 'sold_out'
require_relative 'not_enough_credit'
require_relative 'vending_machine'

# 提供された入力/出力コード: そのままにしておく
input = []
while (line = gets)
  input << line.chomp
end
stock = input[0].split(",").to_h do |entry|
  name, price, count = entry.split(":")
  [name, [price.to_i, count.to_i]]
end
machine = VendingMachine.new(stock)
input.drop(1).each do |line|
  command, arg = line.split
  begin
    case command
    when "insert"
      machine.insert(arg.to_i)
      puts format("credit %.2f", machine.credit / 100.0)
    when "buy"
      puts "bought #{machine.buy(arg)}"
    else
      puts format("refund %.2f", machine.refund / 100.0)
    end
  rescue UnknownProduct, SoldOut, NotEnoughCredit => e
    puts e.message
  end
end
begin
  machine.credit = 500
  puts "credit changed"
rescue NoMethodError
  puts "credit is protected"
end

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ