gpt4 book ai didi

ruby - `[]' : no implicit conversion of Symbol into Integer (TypeError) for a simple ruby Hash

转载 作者:太空宇宙 更新时间:2023-11-03 16:20:04 32 4
gpt4 key购买 nike

在我的 ruby​​ 代码中,我定义了一个新的散列:

options = {
host: 'localhost',
user: nil,
file: nil,
}

然后我使用 OptionsParser 解析散列

OptionParser.new do |opts|
opts.banner = 'Usage: ruby-remote-tailer.rb [options]'

opts.on('-h', '--host', 'The host to run ssh session with') do |host|
options[:host] = "#{host}"
end

opts.on('-h', '--user', 'The user account that will run the session') do |user|
options[:user] = "#{user}"
end

opts.on('-f', '--file', 'The file to run the tail on') do |file|
options[:file] = "#{file}"
end
end

然后运行:

options = ARGV.parse!
puts options[:host]

最后一行导致错误 no implicit conversion of Symbol into Integer (TypeError)。我知道我输入的内容是正确的,因为 p options 是有效的。有想法该怎么解决这个吗?

(请注意,我不想像其他答案中建议的那样使用 .each 循环来获取我需要的单个值)。

谢谢。

最佳答案

您没有以多种方式正确使用 OptionParser。

定义选项时,您必须为选项的实际值提供一个占位符。如果不这样做,它将被解释为一个开关,根据是否设置了开关返回 true 或 false。

opts.on('-h', '--host HOST', 'The host to run ssh session with') do |host|
options[:host] = "#{host}"
end

另一个错误是您为主机和用户选项都定义了 -h。您最好为它们中的每一个定义一个不同的字母,无论如何您可能打算为用户提供 -u

但主要问题,即导致错误的原因是您将 #parse! 方法的返回值视为返回解析后的值。但返回值实际上是 ARGV 数组中未被解析器匹配的剩余部分。并且因为您尝试通过按符号请求元素来像散列一样访问它,它会提示,因为数组元素只能由整数值访问。要修复它,只需保留之前的 options 引用,不要将返回值分配给它。

ARGV.parse!

从这里开始,我会给你一些进一步的批评,但我推荐的东西不应该成为任何错误的原因:

此外,您可能会跳过一开始在 Hash 中提供的默认 nil 值,如果您向 Hash 询问未定义的键,无论如何都会为您提供 nil。

options = {
host: 'localhost'
}

我会说在命令行参数数组 ARGV 上调用 #parse!,虽然这似乎是一个选项,但不是很明显。我建议将对解析器的引用保存到变量并调用解析器上的方法。

parser = OptionParser.new do |opts|

end

parser.parse!(ARGV)

如果您愿意甚至可以不带参数调用它,默认情况下它将使用 ARGV。但在我看来,这会再次使您的代码更难理解。

并且您还可以通过插值摆脱值的字符串转换。至少当您实际从命令行参数数组 ARGV 获取值时,您可以非常确定所有元素都是 String 对象。但是,如果您打算向解析器提供并非完全由字符串元素构建的其他数组,则应保留转换。

opts.on('-h', '--host HOST', 'The host to run ssh session with') do |host|
options[:host] = host
end

另请注意,有一个非常非常普遍的约定,即您在 Ruby 代码中的每个缩进级别使用正好两个空格。在您的示例中,您使用了四个和八个空格,许多 Rubyists 会非常不喜欢。查看The Ruby styleguide获取更多信息。

这是您的代码的修正版本:

#!/usr/bin/env ruby

require 'optionparser'

options = {
host: 'localhost'
}

parser = OptionParser.new do |opts|
opts.banner = 'Usage: ruby-remote-tailer.rb [options]'

opts.on('-h', '--host HOST', 'The host to run ssh session with') do |host|
options[:host] = host
end

opts.on('-u', '--user USER', 'The user account that will run the session') do |user|
options[:user] = user
end

opts.on('-f', '--file FILE', 'The file to run the tail on') do |file|
options[:file] = file
end
end

parser.parse!(ARGV)
puts options[:host]

关于ruby - `[]' : no implicit conversion of Symbol into Integer (TypeError) for a simple ruby Hash,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34981788/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com