2011-05-31 128 views
7

我正在寫一個函數,它需要在ping基於web的API時捕獲一個速率限制錯誤。Sys.sleep()之前沒有執行的函數()

我使用tryCatch捕獲錯誤,而這個函數裏面我指定以下誤差函數:

error=function(e) { 
       warning(paste(e,"\nWaiting an hour for rate limit to reset...")) 
       Sys.sleep(3600) # Wait an hour for rate-limit to reset 
       return(user.info(user, ego.count)) 
      } 

的功能似乎工作,但檢查輸出日誌劇本時,我注意到,警告信息不會被寫入,直到的睡眠時間已用完。

我可以在與R控制檯重現此問題:前Drew sucks被打印到控制檯

print("Drew sucks") 
Sys.sleep(10) 

十秒鐘通過。在我的功能中,我想在暫停發生之前向用戶提供一些關於這種長時間停頓的反饋。

是什麼導致了這種行爲?

回答

3

對於它的地獄,請嘗試:

system(sprintf('sleep %d', seconds)) 

假設你已經有了路徑通常的* NIX睡眠命令。

+1

有一件事 - 如果使用'warning',那麼用戶可以使用'suppressWarnings'來不顯示消息。採用這種解決方案需要另一種方法。 – Marek 2011-06-01 08:11:13

2

可能與輸出緩衝 - 見?flush.console

+0

另一方面,控制檯I/O永遠不會被緩衝。 r可能是一個例外,但這將是一個驚喜,不是嗎?另一種方案的靈感,我想看看(doh)... – TheBlastOne 2011-05-31 21:45:41

+2

添加'flush.console()'並沒有解決從上面的「德魯吸」示例中的問題。 – DrewConway 2011-05-31 21:51:09

3

默認情況下,警告不立即打印,而不是他們的頂級函數返回後打印出來。如果要立即打印,可以設置警告爲'1',如果您想要停止打印,則設置爲更高。

+0

嗯,重新閱讀你的文章後,我不確定我是否真的在回答正確的問題。我以爲你是在說要讓警告()立即打印出來,是嗎? – geoffjentry 2011-05-31 21:45:32

+0

我這樣做,但問題似乎只適用於'warning'調用,就像我的'print'示例一樣。 – DrewConway 2011-05-31 21:50:10

+0

這就是讓我覺得我可能不會在提問的問題。如果我啓動R並運行您的打印示例,我會得到打印輸出,然後是延遲。如果在Sys.sleep()之前爲你做同樣的事情確實沒有執行print(),那麼其他事情正在發生(例如Hadley的回答)。 我確實認爲你會碰到問題w /警告()正在一個函數或者雖然。 – geoffjentry 2011-05-31 21:52:15

7

您需要將immediate.=TRUE設置爲警告功能或設置options(warn=1);和可能需要在調用Sys.sleep()之前添加flush.console()(在某些操作系統上)。

foo <- function() { 
    warning("uh-oh...", immediate.=TRUE) 
    flush.console() 
    Sys.sleep(5) 
    "done" 
} 
foo() 
# Warning in foo() : uh-oh... 
# [1] "done" 

具體細節在?warning的「詳細信息」部分詳細說明。要解釋,「如果選項(警告= 0),警告將在頂層功能完成後存儲並打印;如果選項(警告= 1),則會在打印時發出警告。

+0

這可能是一個操作系統問題,但在OS X上,該函數在打印警告之前仍然執行'Sys.sleep'調用。 – DrewConway 2011-05-31 22:00:29

+0

它適用於Windows和Ubuntu(而且Ubuntu不需要'flush.console()')。 – 2011-05-31 22:02:51

+0

@DrewConway它適用於我通過終端運行的OSX。你在GUI中嗎? (或者更具體地說 - 哪一個,如果是的話) – 2011-05-31 22:12:48