Вопрос

I have experienced some ODD behavior from the code below:

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}.."

When I pass true to have $DEBUG set to true on execution I get an error from name = gets and I have no idea why. If I don't pass parameters via the command line everything works fine.

This is the error output:

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>

If I need to I can post the class definition, but I don't think it's part of the problem.

Это было полезно?

Решение

gets reads from stdin if no arguments are passed, and from the file that was passed as an argument otherwise. You are passing an argument true, ergo gets tries to read from a file named true, which apparently doesn't exist.

This is the very first sentence of the documentation of gets:

Returns (and assigns to $_) the next line from the list of files in ARGV (or $*)

Другие советы

This wouldn't cause a problem on *nix, but I expect Windows, or Ruby on Windows, isn't handling the additional command-line parameter the same way. On *nix, we can use -- between the script name and the parameter to tell the OS not to pass the parameter as a flag. In other words, Ruby wouldn't see true, your script would.

ruby some_script.rb -- options 

But, in general, I think you're doing it wrong and recommend handling your command-line options in a standard way by using the OptionParser class:

require 'optparse'

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

puts $DEBUG

Running that several times on my Mac OS system, with different parameters, gives me:

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

You might still have to use -- to tell the OS and called app which parameters belong to what.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top