Ruby gets方法在从控制台传递参数时抛出异常

时间:2013-05-19 22:46:38

标签: ruby shell command-line argv gets

我从以下代码中体验过一些ODD行为:

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>

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

2 个答案:

答案 0 :(得分: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

您可能仍需要使用--告诉操作系统并调用应用程序哪些参数属于哪些参数。

答案 1 :(得分:1)

如果没有传递参数,

gets将从stdin读取,否则从作为参数传递的文件读取。您正在传递参数true,ergo gets尝试从名为true的文件中读取,该文件显然不存在。

这是gets文档的第一句话:

  

$_(或ARGV

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