2010-01-30 28 views
14

Tôi đang sử dụng gets để tạm dừng đầu ra của tập lệnh cho đến khi người dùng nhấn phím enter. Nếu tôi không vượt qua bất kỳ đối số nào để kịch bản của tôi thì nó hoạt động tốt. Tuy nhiên, nếu tôi chuyển bất kỳ đối số nào cho tập lệnh của tôi thì sẽ bị chết với lỗi sau:Tại sao lại bị lỗi khi đối số được chuyển đến tập lệnh ruby ​​của tôi?

ruby main.rb -i 
main.rb:74:in `gets': No such file or directory - -i (Errno::ENOENT) 
    from main.rb:74:in `gets' 
    ... 

Thông báo lỗi hiển thị đối số tôi đã chuyển đến tập lệnh. Tại sao sẽ được nhìn vào ARGV?

Tôi đang sử dụng OptionParser để phân tích đối số dòng lệnh của mình. Nếu tôi sử dụng parse! thay vì parse (để nó loại bỏ những thứ mà nó phân tách khỏi danh sách đối số) thì ứng dụng hoạt động tốt.

Vì vậy, có vẻ như đang được đọc từ ARGV vì một lý do nào đó. Tại sao? Đây có phải là dự kiến ​​không? Có cách nào để làm cho nó không làm điều đó (làm gets() không giúp được).

Trả lời

22

Ruby sẽ tự động xử lý các đối số chưa được phân loại làm tên tệp, sau đó mở và đọc các tệp làm cho đầu vào có sẵn cho ARGF ($<). Theo mặc định, gets đọc từ ARGF. Để bỏ qua rằng:

$stdin.gets 

Nó đã được gợi ý rằng bạn có thể sử dụng STDIN thay vì $stdin, nhưng nó thường better to use $stdin.

Thêm vào đó, sau khi bạn nắm bắt được đầu vào mà bạn muốn từ ARGV, bạn có thể sử dụng:

ARGV.clear 

Sau đó, bạn sẽ được tự do gets mà không có nó đọc từ tập tin mà bạn có thể không cố ý đọc.

4

toàn bộ điểm của Kernel#gets là để xử lý các đối số được chuyển đến chương trình dưới dạng tên tệp và đọc các tệp đó. Câu đầu tiên trong the documentation đọc:

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

Đó chỉ là cách gets công trình. Nếu bạn muốn đọc từ một đối tượng cụ thể cụ thểIO (ví dụ: $stdin), chỉ cần gọi gets trên đối tượng đó.

Các vấn đề liên quan