我将一个数组传递给我编写的 ruby 方法,但是 ruby 看到了一个定数?
I pass an array to a ruby method I wrote but ruby sees a fixnum?
各位,我是超级 Ruby n00b,我的第一个 Ruby 程序运行时遇到问题。我在 Stack Overflow 上找到了与我遇到的问题密切相关的问答,但无论我尝试什么,我都无法摆脱这个错误。
我写了两个 classes,Checkout 和 Register。这是完整的寄存器 class:
<code>
load 'Register.rb'
class Checkout
def initialize
@register = Register.new
@itemCount = Hash['CH1', 0, 'AP1', 0, 'CF1', 0, 'MK1', 0]
@@inventory = Hash['CH1', 3.11, 'AP1', 6.00, 'CF1', 11.23, 'MK1', 4.75]
@@discount = Hash['CF1', ['BOGO', '@itemCount["CF1"]%2==0', -11.23, '@register.findLast("CF1")'], 'AP1', ['APPL', '@itemCount["AP1"]>=3', -1.50, '@itemCount["AP1"]==3 ? @register.findAll("AP1") : @register.findLast("AP1")'], 'MK1', ['CHMK', '@itemCount["MK1"]==1 && @itemCount["CH1"]==1', -4.75, '@register.findAll("MK1")']]
end
def scan(item)
#get price of item from inventory
price = @@inventory[item]
#add item and price to register
@register.ringUp(item, price)
@itemCount[item]+=1
#find and apply any applicable special
discountCheck = @@discount[item]
unless discountCheck == nil
nameOfDiscount = @@discount[item][0]
discountCondition = @@discount[item][1]
moneyOff = @@discount[item][2]
howToGetItemIndex = @@discount[item][3]
if(eval(discountCondition))
ind = eval(howToGetItemIndex)
if(ind.class == "Array")
@register.applyDiscount(ind, moneyOff, nameOfDiscount)
else #it's a Fixnum so we want to put it in an array first
indArray = [ind]
@register.applyDiscount(indArray, moneyOff, nameOfDiscount)
end
end
end
end
end
</code>
这是寄存器class:
<code>
class Register
def initialize
@itemsInOrderOfScan = Array.new
@itemInfoInOrderOfScan = Array.new
end
def ringUp(item, price)
@itemsInOrderOfScan.push(item)
@itemInfoInOrderOfScan.push(['', price])
end
def applyDiscount(indices, moneyOff, nameOfDiscount)
for i in 0..indices.length-1
ind = indices[i]
newInd = ind + 1
@itemsInOrderOfScan.insert(newInd, '')
@itemInfoInOrderOfScan.insert(newInd, [nameOfDiscount, moneyOff])
end
end
def findLast(item)
arr = Array.new
ind = @itemsInOrderOfScan.rindex(item)
arr.push(ind)
arr
end
def findAll(item)
indexOfFirstInstanceOfItem = @itemsInOrderOfScan.index(item)
arr = findLast(item)
indexOfLastInstanceOfItem = arr.at(0)
for i in indexOfFirstInstanceOfItem..indexOfLastInstanceOfItem
if(@itemsInOrderOfScan.at(i) == item)
arr.push(i)
end
end
arr
end
def printReceipt
puts "Item\t\t\tPrice"
puts "----\t\t\t-----"
total = 0
for i in 0..@itemsInOrderOfScan.length-1
currentItem = @itemsInOrderOfScan.at(i)
currentDiscountName = @itemInfoInOrderOfScan.at(i)[0]
currentPrice = @itemInfoInOrderOfScan.at(i)[1]
total += currentPrice
puts "#{currentItem}\t#{currentDiscountName}\t\t#{currentPrice}"
end
puts "-----------------------------------\n\t\t\t#{total}"
end
end
</code>
当我尝试 运行 时,这些 classes 的工作方式如下:我向 Checkout 提供各种项目,两个 classes 一起工作以创建收据显示已购买的商品以及我调用 printReceipt 方法时可以应用的任何折扣。
我用来调试的测试如下所示:
<code>
load 'Checkout.rb'
basket = ['CH1', 'AP1', 'AP1', 'AP1', 'MK1']
co = Checkout.new
for i in 0..basket.length
puts basket.at(i)
co.scan(basket[i])
end
co.register.print()
</code>
我运行测试时的输出是这样的:
<code>
CH1
AP1
AP1
AP1
Register.rb:16:in `+': no implicit conversion of Fixnum into Array (TypeError)
from Register.rb:16:in `block in applyDiscount'
from Register.rb:14:in `each'
from Register.rb:14:in `applyDiscount'
from Checkout.rb:33:in `scan'
from main.rb:9:in `block in <main>'
from main.rb:7:in `each'
from main.rb:7:in `<main>'
</code>
请帮忙!
提前致谢。
你需要修复4个地方,
在Checkout.rb
中,if(ind.class == "Array")
是错误的比较
使用if(ind.class.to_s == "Array")
或更好地使用if(ind.instance_of? Array)
在你 main.rb
中,使用 for i in 0...basket.length
而不是 for i in 0..basket.length
因为 1..2
=> [1,2] 但 1...3
=> [1,2]
在Checkout.rb
中,在Class之后第一行应该是attr_accessor :register
因为你是在main.rb
[=中访问注册的48=]
在main.rb
中,co.register.printReceipt
而不是co.register.print()
main.rb :
load 'Checkout.rb'
basket = ['CH1', 'AP1', 'AP1', 'AP1', 'MK1']
co = Checkout.new
for i in 0...basket.length
puts basket.at(i)
co.scan(basket[i])
end
co.register.printReceipt
Checkout.rb :
load 'Register.rb'
class Checkout
attr_accessor :register
def initialize
@register = Register.new
@itemCount = Hash['CH1', 0, 'AP1', 0, 'CF1', 0, 'MK1', 0]
@@inventory = Hash['CH1', 3.11, 'AP1', 6.00, 'CF1', 11.23, 'MK1', 4.75]
@@discount = Hash['CF1', ['BOGO', '@itemCount["CF1"]%2==0', -11.23, '@register.findLast("CF1")'], 'AP1', ['APPL', '@itemCount["AP1"]>=3', -1.50, '@itemCount["AP1"]==3 ? @register.findAll("AP1") : @register.findLast("AP1")'], 'MK1', ['CHMK', '@itemCount["MK1"]==1 && @itemCount["CH1"]==1', -4.75, '@register.findAll("MK1")']]
end
def scan(item)
#get price of item from inventory
price = @@inventory[item]
#add item and price to register
@register.ringUp(item, price)
p item
p @itemCount[item]
@itemCount[item]+=1
#find and apply any applicable special
discountCheck = @@discount[item]
unless discountCheck == nil
nameOfDiscount = @@discount[item][0]
discountCondition = @@discount[item][1]
moneyOff = @@discount[item][2]
howToGetItemIndex = @@discount[item][3]
if(eval(discountCondition))
ind = eval(howToGetItemIndex)
if(ind.class.to_s == "Array")
@register.applyDiscount(ind, moneyOff, nameOfDiscount)
else #it's a Fixnum so we want to put it in an array first
indArray = [ind]
@register.applyDiscount(indArray, moneyOff, nameOfDiscount)
end
end
end
end
end
各位,我是超级 Ruby n00b,我的第一个 Ruby 程序运行时遇到问题。我在 Stack Overflow 上找到了与我遇到的问题密切相关的问答,但无论我尝试什么,我都无法摆脱这个错误。
我写了两个 classes,Checkout 和 Register。这是完整的寄存器 class:
<code>
load 'Register.rb'
class Checkout
def initialize
@register = Register.new
@itemCount = Hash['CH1', 0, 'AP1', 0, 'CF1', 0, 'MK1', 0]
@@inventory = Hash['CH1', 3.11, 'AP1', 6.00, 'CF1', 11.23, 'MK1', 4.75]
@@discount = Hash['CF1', ['BOGO', '@itemCount["CF1"]%2==0', -11.23, '@register.findLast("CF1")'], 'AP1', ['APPL', '@itemCount["AP1"]>=3', -1.50, '@itemCount["AP1"]==3 ? @register.findAll("AP1") : @register.findLast("AP1")'], 'MK1', ['CHMK', '@itemCount["MK1"]==1 && @itemCount["CH1"]==1', -4.75, '@register.findAll("MK1")']]
end
def scan(item)
#get price of item from inventory
price = @@inventory[item]
#add item and price to register
@register.ringUp(item, price)
@itemCount[item]+=1
#find and apply any applicable special
discountCheck = @@discount[item]
unless discountCheck == nil
nameOfDiscount = @@discount[item][0]
discountCondition = @@discount[item][1]
moneyOff = @@discount[item][2]
howToGetItemIndex = @@discount[item][3]
if(eval(discountCondition))
ind = eval(howToGetItemIndex)
if(ind.class == "Array")
@register.applyDiscount(ind, moneyOff, nameOfDiscount)
else #it's a Fixnum so we want to put it in an array first
indArray = [ind]
@register.applyDiscount(indArray, moneyOff, nameOfDiscount)
end
end
end
end
end
</code>
这是寄存器class:
<code>
class Register
def initialize
@itemsInOrderOfScan = Array.new
@itemInfoInOrderOfScan = Array.new
end
def ringUp(item, price)
@itemsInOrderOfScan.push(item)
@itemInfoInOrderOfScan.push(['', price])
end
def applyDiscount(indices, moneyOff, nameOfDiscount)
for i in 0..indices.length-1
ind = indices[i]
newInd = ind + 1
@itemsInOrderOfScan.insert(newInd, '')
@itemInfoInOrderOfScan.insert(newInd, [nameOfDiscount, moneyOff])
end
end
def findLast(item)
arr = Array.new
ind = @itemsInOrderOfScan.rindex(item)
arr.push(ind)
arr
end
def findAll(item)
indexOfFirstInstanceOfItem = @itemsInOrderOfScan.index(item)
arr = findLast(item)
indexOfLastInstanceOfItem = arr.at(0)
for i in indexOfFirstInstanceOfItem..indexOfLastInstanceOfItem
if(@itemsInOrderOfScan.at(i) == item)
arr.push(i)
end
end
arr
end
def printReceipt
puts "Item\t\t\tPrice"
puts "----\t\t\t-----"
total = 0
for i in 0..@itemsInOrderOfScan.length-1
currentItem = @itemsInOrderOfScan.at(i)
currentDiscountName = @itemInfoInOrderOfScan.at(i)[0]
currentPrice = @itemInfoInOrderOfScan.at(i)[1]
total += currentPrice
puts "#{currentItem}\t#{currentDiscountName}\t\t#{currentPrice}"
end
puts "-----------------------------------\n\t\t\t#{total}"
end
end
</code>
当我尝试 运行 时,这些 classes 的工作方式如下:我向 Checkout 提供各种项目,两个 classes 一起工作以创建收据显示已购买的商品以及我调用 printReceipt 方法时可以应用的任何折扣。
我用来调试的测试如下所示:
<code>
load 'Checkout.rb'
basket = ['CH1', 'AP1', 'AP1', 'AP1', 'MK1']
co = Checkout.new
for i in 0..basket.length
puts basket.at(i)
co.scan(basket[i])
end
co.register.print()
</code>
我运行测试时的输出是这样的:
<code>
CH1
AP1
AP1
AP1
Register.rb:16:in `+': no implicit conversion of Fixnum into Array (TypeError)
from Register.rb:16:in `block in applyDiscount'
from Register.rb:14:in `each'
from Register.rb:14:in `applyDiscount'
from Checkout.rb:33:in `scan'
from main.rb:9:in `block in <main>'
from main.rb:7:in `each'
from main.rb:7:in `<main>'
</code>
请帮忙!
提前致谢。
你需要修复4个地方,
在
Checkout.rb
中,if(ind.class == "Array")
是错误的比较使用
if(ind.class.to_s == "Array")
或更好地使用if(ind.instance_of? Array)
在你
main.rb
中,使用for i in 0...basket.length
而不是for i in 0..basket.length
因为1..2
=> [1,2] 但1...3
=> [1,2]在
[=中访问注册的48=]Checkout.rb
中,在Class之后第一行应该是attr_accessor :register
因为你是在main.rb
在
main.rb
中,co.register.printReceipt
而不是co.register.print()
main.rb :
load 'Checkout.rb'
basket = ['CH1', 'AP1', 'AP1', 'AP1', 'MK1']
co = Checkout.new
for i in 0...basket.length
puts basket.at(i)
co.scan(basket[i])
end
co.register.printReceipt
Checkout.rb :
load 'Register.rb'
class Checkout
attr_accessor :register
def initialize
@register = Register.new
@itemCount = Hash['CH1', 0, 'AP1', 0, 'CF1', 0, 'MK1', 0]
@@inventory = Hash['CH1', 3.11, 'AP1', 6.00, 'CF1', 11.23, 'MK1', 4.75]
@@discount = Hash['CF1', ['BOGO', '@itemCount["CF1"]%2==0', -11.23, '@register.findLast("CF1")'], 'AP1', ['APPL', '@itemCount["AP1"]>=3', -1.50, '@itemCount["AP1"]==3 ? @register.findAll("AP1") : @register.findLast("AP1")'], 'MK1', ['CHMK', '@itemCount["MK1"]==1 && @itemCount["CH1"]==1', -4.75, '@register.findAll("MK1")']]
end
def scan(item)
#get price of item from inventory
price = @@inventory[item]
#add item and price to register
@register.ringUp(item, price)
p item
p @itemCount[item]
@itemCount[item]+=1
#find and apply any applicable special
discountCheck = @@discount[item]
unless discountCheck == nil
nameOfDiscount = @@discount[item][0]
discountCondition = @@discount[item][1]
moneyOff = @@discount[item][2]
howToGetItemIndex = @@discount[item][3]
if(eval(discountCondition))
ind = eval(howToGetItemIndex)
if(ind.class.to_s == "Array")
@register.applyDiscount(ind, moneyOff, nameOfDiscount)
else #it's a Fixnum so we want to put it in an array first
indArray = [ind]
@register.applyDiscount(indArray, moneyOff, nameOfDiscount)
end
end
end
end
end