0

我从下面的代码中经历了一些奇怪的行为:

require 'CSV'

$DEBUG = ARGV.empty? ? false : ARGV[0] #Global debug flag.

class PhoneBook
  #class code here etc etc
end

PhoneBook.start_dir = "file-io-samples/phonebooks/"
puts "Enter a phonebook!"
name = gets #This is the problem.
puts "Using #{name}.."

当我通过 true$DEBUG在执行时设置为 true 时,我收到一个错误name = gets,我不知道为什么。如果我不通过命令行传递参数,一切正常。

这是错误输出:

C:\Pickaxe>ruby PhoneBook.rb
Enter a phonebook!
Hurrah! Works
Using Hurrah! Works
..

C:\Pickaxe>ruby PhoneBook.rb true
Enter a phonebook!
Exception `Errno::ENOENT' at PhoneBook.rb:62 - No such file or directory - true
PhoneBook.rb:62:in `gets': No such file or directory - true (Errno::ENOENT)
        from PhoneBook.rb:62:in `gets'
        from PhoneBook.rb:62:in `<main>'

C:\Pickaxe>

如果需要,我可以发布类定义,但我认为这不是问题的一部分。

4

2 回答 2

1

这不会在 *nix 上造成问题,但我希望 Windows 或 Windows 上的 Ruby 不会以相同的方式处理额外的命令行参数。在 *nix 上,我们可以--在脚本名称和参数之间使用来告诉操作系统不要将参数作为标志传递。换句话说,Ruby 不会看到true,你的脚本会。

ruby some_script.rb -- options 

但是,总的来说,我认为您做错了,建议您使用OptionParser类以标准方式处理命令行选项:

require 'optparse'

OptionParser.new do |opt|
  opt.on('-d', '--[no-]debug') { |o| $DEBUG = o }
end.parse!

puts $DEBUG

在我的 Mac OS 系统上运行几次,使用不同的参数,给我:

$ ruby test.rb
false
$ ruby test.rb --no-debug
false
$ ruby test.rb -d
true
$ ruby test.rb --debug
true

您可能仍然需要使用--来告诉操作系统和调用的应用程序哪些参数属于什么。

于 2013-05-19T23:08:40.280 回答
1

gets如果没有传递参数,则从标准输入读取,否则从作为参数传递的文件中读取。您正在传递一个参数true,ergogets尝试从名为 的文件中读取,该文件true显然不存在。

这是文档的第一句话gets

从(或)中的文件列表中返回(并分配给$_)下一行ARGV$*

于 2013-05-20T03:06:08.807 回答