2009-11-13 46 views
15

當使用Proc#調用在Ruby中調用lambda函數時,self總是以定義函數時的值爲結束,而不是函數的函數值被稱爲,例如:使用Proc時爲自己提供值#調用

$p = lambda { self } 

class Dummy 
    def test 
    $p.call 
    end 
end 

d = Dummy.new 

> d.test 
=> main 

調用test回報main,當我打算這回是#<Dummy:0xf794> - 的Dummy一個實例,這是在那裏我叫$p代碼點的self值。

在Javascript中,我只想傳遞我想成爲「被調用者」的對象作爲call的第一個參數。 Ruby中是否有這樣的功能,允許我設置一個任意對象,或者至少當前值self作爲self的新值,當我調用Proc時?

+0

我曾經想過'$ p.bind(some_object)'可能會起作用,但顯然'bind'只能用於'UnboundMethod'對象。一個過程可以被強制成一個無約束的方法嗎? – 2009-11-13 14:32:23

回答

15

您正在尋找instance_eval,它將在調用對象的上下文中計算一個lambda。

>> $p = proc { self } 
=> #<Proc:[email protected](irb):1 (lambda)> 
>> class Dummy 
>> def test 
>>  $p.call 
>> end 
>> 
>> def test1 
>>  instance_eval(&$p) 
>> end 
>> end 

>> d = Dummy.new 
=> #<Dummy:0x946f7c8> 
>> d.test 
=> main 
>> d.test1 
=> #<Dummy:0x946f7c8> 
+1

當我嘗試以這種方式發送一個塊到'instance_eval'時,我總是得到錯誤'ArgumentError:錯誤的參數數量(1代表0)'。我認爲@shwoodard的答案現在是正確的答案。 – nzifnab 2014-09-30 17:47:18

+0

使用'proc'而不是'lamda'應該解決'ArgumentError:錯誤的參數數量(1代表0)'異常。 – 2014-12-01 18:18:59

+0

謝謝雅各布,我已經更新了代碼 – 2014-12-01 22:46:42

1

lambda定義了一個閉包,這意味着它將封裝它定義時的環境。如果你想讓自己成爲調用者,只需定義一個常規方法或更好地使用塊。

+0

謝謝 - 我知道lambda創建了一個閉包,並且我想保留對封裝環境的訪問,但只是重寫一個特殊變量'self'。你有什麼想法可以做到這一點? – 2009-11-13 12:36:36

19

您可能想要使用instance_exec,因爲它允許您將參數傳遞給塊,而instance_eval不允許。

def eval_my_proc_with_args(*args, &block) 
    instance_exec(*args, &block) 
end 
相關問題