2014-07-08 57 views
3

我有一個簡單的腳本處理來自STDIN的行。有時會出現一個異常 - 一些UTF-8轉換錯誤 - 我想檢查變量,導致錯誤的原因。我用下面的語法在我的文件(讓我們稱之爲filter.rb),但我從來沒有撬提示:如何用Pry測試類似過濾器的Ruby腳本?

#!/usr/bin/ruby 
require "pry" 

n=0 
while line=STDIN.gets do 
begin 
    n=n+1 
    raise "an exception" if n==2 
rescue => e 
    binding.pry 
end 
end 

當我發出:

cat data.txt|ruby filter.rb 

我在屏幕上看到:

 5: while line= STDIN.gets do 
    6: begin 
    7:  n=n+1 
    8:  raise "an exception" if n==2 
    9: rescue => e 
=> 10:  binding.pry 
    11: end 
    12: end 

但事實上,我所得到的只是一個bash提示符,而不是一個Pry命令提示符。

+0

如果我運行「ruby filter.rb」,並從鍵盤提供標準輸入,並以Ctrl + D結尾,它就可以工作。如果我管道形成文件,它不會再工作。也許我的txt文件包含一些導致Pry退出的文本或字符。 – Konstantin

+0

你的文件是否有換行符? – vgoff

+1

創建一個較小的文件,或增加if語句中的數字2。我相信該文件的管道正在導致撬接受額外的線。而不是使用STDIN使用文件來測試這個。 – vgoff

回答

4

問題是Pry使用Readline,它反過來從標準輸入讀取。如果你使用ruby作爲過濾器,stdin不再是一個終端(isatty將是false)。因此,Readline將無法使用stdin並默默地遊行(或者,如果您幸運的話,會給出語法錯誤並前進)。

您可以通過添加

require "readline" 
Readline.input = IO.new(IO.sysopen("/dev/tty", "r+")) 

你的代碼給Readline工作的tty。

Pry文檔暗示了這個解決方案,但我不知道這是否受到Pry的制裁,或者它是否會與Pry,Ruby的其他部分以及您的應用程序中可能存在的其他任何部分產生奇怪的交互。 YMMV。

+0

在Ruby 2.4.1中,readline修復不適用於我。但是這是:'''要求'撬'; pry_in = IO.new(IO.sysopen(「/ dev/tty」,「r +」)); Pry.config.input = pry_in; binding.pry''' –

0

我認爲BertD的答案會正常工作。

最容易要做的事情就是剛剛讀取正常的文件,(大約)如

File.new("data.txt").each_line do |line| 
    begin 
    n += 1 
    raise "an exception" if n == 2 
    rescue => e 
    binding.pry 
    end 
end 

我還鼓勵類/方法封裝處理,如何的數據到輸入是一個單獨的問題,發生到數據。它還使得獨立調試更容易。

+0

這是文化的衝突! Unix方式是讓所有東西都成爲過濾器。 Ruby的方式不應該咬Unix的方式。我個人認爲這是一個bug,默認情況下readline從stdin而不是/ dev/tty讀取。 – BertD

+0

也就是說,在學習Ruby之後,我學會了將操作系統界面從業務邏輯中快速分離出來,正是因爲像這樣的Readline這樣的小缺陷真正懲罰了像我這樣用Perl思維方式進行插入的老屁 - 我感到開明。 [對不起,被添加註釋按鈕的Enter鍵綁定咬住了;還在學習關於stackoverflow] – BertD