ruby - 尝试在 Ruby 中实例化自定义对象时抛出(参数错误)
问题描述
我想从我写在不同文件上的类中实例化一个对象。我得到的是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)
我做错了什么?
解决方案
在 Ruby 中,方法定义也是表达式(实际上,在 Ruby 中,一切都是表达式,没有语句),因此它们的计算结果是一个对象。方法定义表达式求值为 aSymbol
表示已定义方法的名称。
所以,
def initialize(*) end
#=> :initialize
在您的代码中,后面有一个逗号attr_reader :slots
,这意味着您将两个参数传递给attr_reader
,即符号:slots
和表达式def initialize(…) … end
。由于 Ruby 是一门严格的语言,因此在执行自身attr_reader
之前,将首先评估to 的参数。attr_reader
所以,首先发生的是方法定义表达式被求值。这定义了一个名为的(私有)方法initialize
。它还计算符号:initialize
。
接下来,对表达式attr_reader :slots, :initialize
进行求值,它定义了两个名为slots
andinitialize
的方法,从而覆盖了您刚刚定义的方法。请注意,这将打印一个警告:
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
和$stdout
是stdin:
和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
推荐阅读
- json - 将反应上下文作为 JSON,但不能真正访问它的部分
- xml - 如何在rest API Flutter中发布/发送XML数据而不是JSON?
- vba - 将数据从 Word 复制到 Outlook 正文并保持格式
- python - 无法使用 recommonmark 将 README.md 的相对路径添加到 Sphinx
- c++ - QStackWidget - 按名称搜索
- entity-framework - 带有 asp.net 核心网络应用程序、EF 核心和 SignalR 的实时数据表
- installation - 当运行一个新的 uwp 应用程序作为旧应用程序的更新时,有没有办法在安装时不删除本地状态?
- angular - 角度反应形式的字段形式值的前缀值
- php - 此路由不支持 PUT 方法。支持的方法:GET、HEAD、POST。当我使用@method('PUT')
- swift - UIImage 在 .launchimage UIImage 命令上返回 nil