Ruby - 用错误数量的参数初始化对象

时间:2013-06-07 21:04:36

标签: ruby initialization

在下面的代码中我收到以下错误:“sandbox2.rb:150:in`initialize':错误的参数数量(4表示0)(ArgumentError)”虽然我认为参数的数量应该没问题。

程序从多个文件加载数据,在“load_orders”方法中,它应从xml文件中提取两个地址,并创建具有4个参数的对象tmp_order(订单号,日期,帐单地址,送货地址)。但为什么对象不会被创建?我在这里错过了什么?

我也附上order.rb。

# -*- coding: utf-8 -*-

require 'rexml/document'
require 'time'

require_relative "product.rb"
require_relative "store.rb"
require_relative "customer.rb"
require_relative "order.rb"

class Shop
  def initialize(arguments)
    # 1. Overte spravne mnozstvi argumentu. V pripade chyby vyvolejte vyjimku.
    # 2. Ulozte si argumenty do vhodnych promennych pro pozdejsi pouziti

    # vyjimkou osetrime spravny pocet parametru
    begin
      raise Exception.new if arguments.length != 5

    rescue Exception
      puts "Špatný počet parametrů programu."
      puts "Správné použití je: "
      puts "ruby main.rb products.xml store.xml orders.xml store_output.xml customers.xml"
      exit

    end

    puts "Počet parametrů je OK"

    # iterujeme polem arguments a parametry prirazujeme do promennych
    arguments.each do |arg|
      if arg == "orders.xml"
        @fn_orders = arg
      elsif arg == "products.xml"
        @fn_products = arg
      elsif arg == "store.xml"
        @fn_store = arg
      elsif arg == "store_output.xml"
        @fn_out_products = arg
      elsif arg == "customers.xml"
        @fn_out_customers = arg
      end
    end
  end

  def load_products
    # 1. Nactete XML soubor s produkty. V pripade problemu (napr. neexistujici soubor) vyvolejte vyjimku.
    # 2. Prochazejte XML soubor a vytvarejte nove objekty tridy Produkt. Nezapomente odchytavat vyjimky.

    begin

  File.open(@fn_products, "r") do |file|
    doc = REXML::Document.new(file)
    doc.root.elements.each do |elems| 

      # vytvorime produkt s atributy code, name a price
      product = Product.new(elems.attributes["code"].strip,
        elems.elements["name"].text,
          elems.elements["price"].text)
      # vypise atribut code
      # puts elems.attributes["code"].strip

        # vypise podelement name a cena        
        # puts elems.elements["name"].text
        # puts elems.elements["price"].text
      end    
    end

    rescue Exception
      puts "Nelze otevřít soubor #{@fn_products} - konec programu."
    end

  end

  def load_store
    @store = Store.new
    # 1. Nactete XML soubor se stavem skladu. V pripade problemu (napr. neexistujici soubor) vyvolejte vyjimku.
    # 2. Prochazejte XML soubor a volejte @store.add_product.

    begin

    File.open(@fn_store, "r") do |file|
      doc = REXML::Document.new(file)
      doc.root.elements.each do |elems|

        # pridame do @store produkt dle code a nastavime jeho mnozstvi dle amount
        @store.add_product((elems.attributes["code"].strip),(elems.attributes["amount"].strip))
      end
    end

    # osetreni vyjimky pro pripad, ze soubor neexistuje
    rescue Exception
      puts "Nelze otevrit soubor #{@fn_store} - konec programu."
      exit
    end

  end

  def load_orders
    @orders = []
    # 1. Nactete XML soubor s objednavkami. V pripade problemu (napr. neexistujici soubor) vyvolejte vyjimku.
    # 2. Prochazejte XML soubor a pro jednotlive objednavky:
    # 2a. Vytvorte novy objekt tridy Order.
    # 2b. Pro jednotlive polozky objednavky vytvorte novy objekt tridy OrderItem a predejte jej metode add_item.
    # 2c. Pridejte objednavku do pole @orders.

      puts "zacatek load orders"
      gets

#      begin
        File.open(@fn_orders, "r") do |file|
          doc = REXML::Document.new(file)
          doc.root.elements.each do |elems|

            # temp promenne pro ukladani objektu zakazniku
            # spolu s billing a shipping adres
            tmp_bill_addr = ""
            tmp_ship_addr = ""

            # iterujeme pres elementy address
            elems.elements.each("address") do |addr|

              # jmeno a billing address hodnoty ulozime do objektu customer
              if (addr.attributes["type"].strip == "billing")
                tmp_bill_addr = Customer.new(addr.elements["name"].text,
                  Address.new(addr.elements["street"].text, 
                    addr.elements["city"].text,
                      addr.elements["state"].text, 
                        addr.elements["zip"].text,
                          addr.elements["country"].text))
              end
              # jmeno a shipping address hodnoty ulozime do objektu customer
              if (addr.attributes["type"].strip == "shipping")
                tmp_ship_addr = Customer.new(addr.elements["name"].text,
                  Address.new(addr.elements["street"].text, 
                    addr.elements["city"].text, 
                      addr.elements["state"].text, 
                        addr.elements["zip"].text, 
                          addr.elements["country"].text))
              end
            end
            # vytvorime objekt s objednavkou
            puts "ladici vypis ted"
            puts tmp_bill_addr.address.street
            puts elems.attributes["number"]
              puts Time.xmlschema(elems.attributes["date"])
                puts tmp_ship_addr

            puts "here is the problem"
            tmp_order = Order.new(elems.attributes["number"],Time.xmlschema(elems.attributes["date"]),tmp_bill_addr,tmp_ship_addr)
puts tmp_order                
            # dodame do nej jednotlive polozky
#                elems.elements.each("items/item") do |item|
#                  tmp_ord_itm = OrderItem.new(item.attributes["code"],
#                    item.elements["name"].text, item.elements["price"].text,
#                     item.elements["quantity"].text)
#                  tmp_order.add_item(tmp_ord_itm)
#               end    

          puts "tady jsem skoncil"
 #               @orders << tmp_order

          end
        end

#        rescue Exception
#          puts "Nelze otevřít soubor #{@fn_orders} - konec programu."
#          exit
#      end
      puts "konec load orders" 
  end

  def process_order(order)
    # Zpracujte objednavku.
    # Prochazejte jednolive polozky objednavky a provadejte zadane kontroly.
    # V pripade, ze je vse v poradku, upravte stav skladu volanim @store.sell_product.
    # Nezapomente si ulozit udaje o zakaznikovi.
  end

  def process_orders
    # Zpracujte objednavky. Zde se deje samotna logika programu, ktera je podrobne popsana v zadani.
    # Seradte objednavky dle data a v poradi od nejstarsi je zacnete zpracovavat volanim metody process_order.
  end

  def save_store
    # Projdete produkty v @store a ulozte je do XML souboru.
  end

  def save_customers
    # Projdete zakazniky ziskane ze zpracovanych zakazek a ulozte je do XML souboru.
  end

  def run
    # Doplnte reseni vyjimek.
    puts "jsme v runu"
    gets
    load_products
    puts "produkty nacteny"
    gets
    load_store
    puts "sklad nacten"
    load_orders
    process_orders
    save_store
    save_customers
  end
end

shop = Shop.new(ARGV)

shop.run

order.rb

# -*- coding: utf-8 -*-

class OrderItem
  # Doplnte.

  attr_reader :product_code, :product_name, :price, :quantity

  def initialize(product_code, product_name, price, quantity)
    # Doplnte.

    @product_code = product_code
    @product_name = product_name
    @price = price.to_i
    @quantity = quantity.to_i

  end
end

class Order
  # Doplnte.

  attr_reader :order_number, :date, :shipping_address, :billing_address, :items

  def initilize(order_number, date, shipping_address, billing_address)
    # Doplnte.
    @items = []

    @order_number = order_number
    @date = date
    @shipping_address = shipping_address
    @billing_address = billing_address
  end

  def add_item(item)
    @items << item
  end
end

2 个答案:

答案 0 :(得分:3)

班级Order中有拼写错误。

def initilize(order_number, date, shipping_address, billing_address)

应该是

def initialize(order_number, date, shipping_address, billing_address)

这样,你没有覆盖不接受参数的Object的{​​{1}}。相反,您创建了一个永远不会被调用的附加方法initialize

答案 1 :(得分:0)

更改代码中的以下部分def initilize(order_number, date, shipping_address, billing_address)

def initialize(order_number, date, shipping_address, billing_address)
    # Doplnte.
    @items = []

    @order_number = order_number
    @date = date
    @shipping_address = shipping_address
    @billing_address = billing_address
end