2012-09-24 47 views
1

我想看看如果一個具有相同參數的proc調用每次都會得到相同的結果。用參數調用的pureproc是免費的,所以每次我打電話pureproc(1,1)時,我都會得到相同的結果。使用參數調用的參數dirtyproc被綁定在其環境中,因此即使它與pureproc具有相同的參數,其輸出將取決於環境。如何確定一個proc調用是否仍然空閒或綁定?

 
ruby-1.9.2-p136 :001 > envx = 1 
=> 1 
ruby-1.9.2-p136 :003 > pureproc = Proc.new{ |a,b| a+b } 
=> # 
ruby-1.9.2-p136 :004 > dirtyproc = Proc.new{ |a,b| a+b+envx } 

我如何編程方式確定一個名爲PROC或方法是否是免費的,只被綁定在都必須被傳遞的變量定義?任何關於綁定,局部變量等的解釋都會受到歡迎。

+0

我有一種感覺,這相當於解決停機問題,但我無法證明它。 –

+0

大聲笑 - 我沒有在尋找一個解決問題的方法 - 只是關於什麼Ruby知道關於Procs的一些信息,只要他們指的是變量的範圍。 –

回答

0

嗯,棘手。有一個parameters方法告訴你有關預期的參數(注意它們是如何選擇的,因爲你使用的是特效,而不是lambda)。

pureproc.parameters 
=> [[:opt, :a], [:opt, :b]] 
dirtyproc.parameters 
=> [[:opt, :a], [:opt, :b]] 

作爲確定關閉了一個變量是否被實際用於計算PROC的返回值,走在AST想到的(有針對寶石),但似乎累贅。我的第一個想法是類似dirtyproc.instance_eval { local_variables },但由於兩個關閉關閉在相同的環境,顯然不會讓你很遠...

但總體問題是:如果你想確保某件事是純淨的,爲什麼不把它作爲一個適當的方法,在那裏你並沒有首先關閉環境呢?

+0

感謝Michael,如果我定義函數,'def'技巧可能會有所幫助 - 但更多的是在庫(或測試)代碼中詢問可能未知來源的現有Proc。我想AST可能是最後一招。 –

1

也許你可以使用像sourcify這樣的gem解析源代碼,取出所有的標記,並檢查是否有任何變量。但請注意,這與proc/method調用的值不變是不同的概念。例如,如果您的代碼中包含Time.nowRandom.new之類的內容,則不需要定義任何變量,但每次調用時都會有所不同。另外,當proc有envx - envx時,你想要怎麼做?這將保持不變,但仍會影響代碼,除非定義了envx,否則它將返回錯誤。

+0

這個和其他一些問題讓我相信,如果不是不可能在Ruby中「知道」函數的冪等性,那就相當棘手。我仍然在尋找關於它是否關閉了本地未定義的任何變量的答案 –

相關問題