Arrays 我将一个数组传递给我编写的ruby方法,但是ruby看到一个fixnum?

Arrays 我将一个数组传递给我编写的ruby方法,但是ruby看到一个fixnum?,arrays,ruby,typeerror,fixnum,Arrays,Ruby,Typeerror,Fixnum,各位,我是一个超级Ruby n00b,在让我的第一个Ruby程序工作时遇到了问题。我在堆栈溢出上发现了Q和A,它们与我遇到的问题密切相关,但无论我做什么尝试,我都无法摆脱这个错误 我写了两门课,结帐和注册。下面是完整的注册类: <code> load 'Register.rb' class Checkout def initialize @register = Register.new @itemCount = Hash['CH1', 0,

各位,我是一个超级Ruby n00b,在让我的第一个Ruby程序工作时遇到了问题。我在堆栈溢出上发现了Q和A,它们与我遇到的问题密切相关,但无论我做什么尝试,我都无法摆脱这个错误

我写了两门课,结帐和注册。下面是完整的注册类:

<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>
<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>
下面是注册类:

<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>
<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>
当我尝试运行这些类时,这些类的工作方式如下:我为Checkout提供各种项目,这两个类一起创建一个收据,显示购买了什么以及在调用printReceive方法时可以应用的任何折扣

我用于调试的测试如下所示:

<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>
运行测试时的输出如下所示:

<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>

CH1
AP1
AP1
AP1
Register.rb:16:in`+':没有将Fixnum隐式转换为数组(TypeError)
来自Register.rb:16:in'block in applyDiscount'
来自Register.rb:14:in'each'
来自Register.rb:14:in'applyDiscount'
从结帐处。rb:33:in'scan'
从main.rb:9:in'block in'
从main.rb:7:in'each'
从main.rb:7:in`'
请帮忙


提前谢谢。

您需要在4个位置进行修复

  • Checkout.rb
    中,如果(ind.class==“Array”)比较错误,则

    使用
    if(ind.class.to=“Array”)
    或更好地使用
    if(ind.instance\u of?Array)

  • 在您的
    main.rb
    中,使用
    表示0…basket.length中的i,而不是
    表示0…basket.length中的i,因为
    1..2
    =>[1,2]但是
    1…3
    =>[1,2]

  • Checkout.rb
    中,课后第一行应该是
    attr\u accessor:register
    ,因为您在
    main.rb中访问register

  • main.rb
    中,
    co.register.printReceive
    而不是
    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
    

    非常感谢你,阿克法里迪!你把那些虫子都除掉了。我真的很欣赏这双新鲜的眼睛。