尝试在Ruby中实例化自定义对象时抛出(参数错误)

时间:2019-02-03 05:58:25

标签: ruby oop

我想从我在其他文件上编写的类实例化一个对象。我得到的是wrong number of arguments (given 1, expected 0) (ArgumentError)

这是主要代码

# ./lib/parking_lot
require_relative './lot.rb'

class ParkingLotInterface

  def initialize(input: $stdin, output: $stdout)
    @input, @output = input, output
    @lot = nil
  end

  def prompt_input
    @lot = Lot.new(10)   
  end
end

parking_lot_interface = ParkingLotInterface.new(input: $stdin, output: $stdout)

parking_lot_interface.prompt_input

这是对象类

# ./lib/lot
class Lot
  attr_reader :slots, 

  def initialize(size)
    @slots = Arrays.new(size)
  end
end

我尝试实例化一个新的Lot对象的行抛出了错误。在互联网上,遇到相同问题的人被告知他们没有在课堂上指定def initialize或输入了错误的内容。但是,我照他们所说的做,仍然面对wrong number of arguments (given 1, expected 0) (ArgumentError)

我做错了什么?

2 个答案:

答案 0 :(得分:1)

在Ruby中,方法定义也都是表达式(实际上,在Ruby中,所有内容都是一个表达式,没有语句),因此它们求值一个对象。方法定义表达式的计算结果为Symbol,表示所定义方法的名称。

所以

def initialize(*) end
#=> :initialize

在您的代码中,attr_reader :slots后有一个逗号,这意味着您将两个参数传递给attr_reader,即符号:slots和表达式def initialize(…) … end。由于Ruby是一种严格的语言,因此attr_reader本身执行之前,将首先评估attr_reader的参数。

因此,首先发生的是对方法定义表达式进行求值。这定义了一个名为initialize的(私有)方法。它还将计算为符号:initialize

接下来,对表达式attr_reader :slots, :initialize求值,该表达式定义了两个名为slotsinitialize的方法,从而覆盖了您刚刚定义的方法。请注意,这将显示警告:

lot.rb:3: warning: method redefined; discarding old initialize
lot.rb:5: warning: previous definition of initialize was here

您应该始终阅读警告,Ruby开发人员不会花费辛勤的工作将警告放到一边!

解决方案是删除告诉Ruby寻找第二个参数的逗号。

您的代码中还有第二个错误,就是您在Array中错位了Lot#initialize

而且,您可以进行一些风格上的改进:

  • 无需将路径和文件扩展名传递到require_relative。应该是require_relative 'lot'
  • 未初始化的实例变量的值为nil,因此无需将@lot初始化为nil
  • $stdin$stdoutstdin:stdout:关键字参数的默认参数值,因此无需显式传递它们。
  • 几乎不需要创建特定大小的数组,因为Ruby数组是动态的,并且可以随时更改其大小。

考虑到所有这些,您的代码将如下所示:

# ./lib/parking_lot
require_relative 'lot'

class ParkingLotInterface
  def initialize(input: $stdin, output: $stdout)
    @input, @output = input, output
  end

  def prompt_input
    @lot = Lot.new(10)   
  end
end

parking_lot_interface = ParkingLotInterface.new

parking_lot_interface.prompt_input

# ./lib/lot
class Lot
  attr_reader :slots

  def initialize(size)
    @slots = Array.new(size)
    # could be @slots = []
    # depending on how you use `@slots` later
  end
end

答案 1 :(得分:0)

之后删除逗号
attr_reader :slots,

应该是

attr_reader :slots

看看,您正在尝试在lot.rb上实例化数组(并且不得为复数形式)

  def initialize(size)
    @slots = Arrays.new(size)
  end

应该是

  def initialize(size)
    @slots = Array.new(size)
  end