2012-03-26 61 views
2

假設我有一個返回閉包功能:析構函數無類

sub generator 
{ 

    my $resource = get_resource(); 
    my $do_thing = sub 
    { 
    $resource->do_something(); 
    } 

    return $do_thing; 
} 

# new lexical scope 
{ 
    my $make_something_happen = generator(); 

    &$make_something_happen(); 
} 

我希望能夠確保當$make_something_happe n爲從範圍刪除,我能夠調用一些$resource->cleanup();

當然,如果我有一個類,我可以用析構函數做到這一點,但是對於我想要做的事來說,這看起來有點重量級。從建模對象的角度來看,這不是一個「對象」,它只是一個需要在啓動時和死亡之前執行一些代碼的函數。

我該如何在Perl中做這件事(出於好奇,任何語言都支持這種想法)?

+0

是的,其他一些語言支持這一點(儘管除了一些Common Lisp實現(例如SBCL),我不能指定任何其他語言)。它通常被稱爲終結器,而不是析構函數(名稱爲「析構函數」暗示顯式釋放內存)。一個系統函數接受對象(er,* value *)的監視,並在死亡時調用該函數。 – 2012-03-26 22:25:51

回答

4

我只是用這個類。保佑子程序的參考,並仍然像你一樣使用它。 get_resource然後使用這個類。因爲我不知道是什麼樣子呢,我會讓你來整合它:

package Gozer { 
     sub new { 
     my($class, $subref); 
     bless $subref, $class; 
     } 

     sub DESTROY { 
     ...; #cleanup 
     } 
     } 

如果每一件事情可以有它自己的清理工作,我會使用類組的兩個代碼裁判:

package Gozer { 
     sub new { 
     my($class, $subref, $cleanup); 
     bless { run => $subref, cleanup => $cleanup }, $class; 
     } 

     sub DESTROY { 
     $_[0]{cleanup}(); 
     } 
     } 

在Perl中,我不認爲這是重量級。對象系統簡單地將標籤附加到引用。並不是每個對象都需要建模,所以這是一個非常好的對象。

在普通變量上使用某種終結器會很高興,但我認爲這些結果最終會成爲拓撲相同的事物。你可以用Perl做爲tie,但這只是一個對象。

0

我想我理解你的問題。在我的情況下,我想要:
*可在腳本運行期間的任意時間點設置的全局變量
*直至腳本生命週期結束
*明確清理它。

看起來我可以通過定義一個END塊來做到這一點;它將「儘可能晚」地運行。你應該可以做$ resource-> cleanup();在那裏。

這裏更多: http://perldoc.perl.org/perlmod.html#BEGIN%2c-UNITCHECK%2c-CHECK%2c-INIT-and-END

頁面上的begincheck程序有代碼。