2017-08-28 108 views
4

我即將完成學習Intermediate Perl書。SUPER :: methods在Perl中測試分支分配

在第18章對象銷燬介紹以下DESTROY方法定義:

# lib/Animal.pm 
package Animal { 
    # ... 
    sub DESTROY { 
    my $self = shift; 
    if ($self->{temp_filename}){ 
     my $fh = $self->{temp_fh}; 
     close $fh; 
     unlink $self->{temp_filename}; 
    } 
    print '[', $self->name, " has died.]\n"; 
    } 
# ... 
} 

# lib/Horse.pm 
package Horse { 
    use parent qw(Animal) 
    # ... 
    sub DESTROY { 
    my $self = shift; 
    $self->SUPER::DESTROY if $self->can('SUPER::DESTROY'); 
    print "[", $self->name, " has gone off to the glue factory.]\n"; 
    } 
# ... 
} 

幾個後不成功的嘗試,我寫了基於this answer這個測試:

# t/Horse.t 
#!perl -T 

use strict; 
use warnings; 
use Test::More tests => 6; 
use Test::Output; 
# some other tests 

# test DESTROY() when SUPER::DESTROY is not defined; 
{ 
    my $tv_horse = Horse->named('Mr. Ed'); 
    stdout_is(sub { $tv_horse->DESTROY }, "[Mr. Ed has died.]\n[Mr. Ed has gone off to the glue factory.]\n", 
     'Horse DESTROY() when SUPER::DESTROY is defined'); 
} 

{ 
    my $tv_horse = Horse->named('Mr. Ed'); 
    sub Animal::DESTROY { undef } 
    stdout_is(sub { $tv_horse->DESTROY }, "[Mr. Ed has gone off to the glue factory.]\n", 
     'Horse DESTROY() when SUPER::DESTROY is not defined'); 
} 

我無法測試由於方法重定義sub Animal::DESTROY { undef }也影響前一個程序段中的測試,所以兩種情況下的輸出均正確。

您是否知道確保方法重新定義按預期工作的方法?

感謝

+2

如果你正在寫的'Animal'類和'Animal'總是與'馬一起使用',那麼你知道'Animal'提供了DESTROY方法 - ' - > can('SUPER :: DESTROY')檢查變得有點不必要。我只是直接調用'$ self-> SUPER :: DESTROY'。 – amon

+3

Btw不要通過直接調用它來觸發DESTROY方法,這可能會多次調用DESTROY。相反,'undef $ tv_horse'清除將觸發析構函數的變量。 – amon

+0

好的,謝謝你的建議 – mabe02

回答

6

這應該設置移除/重新定義子程序只有等到封閉塊結束,

{ 
    # not needed when removing method 
    # no warnings 'redefine'; 

    my $tv_horse = Horse->named('Mr. Ed'); 
    # returns undef 
    # local *Animal::DESTROY = sub { undef }; 

    # remove the mothod until end of the enclosing block 
    local *Animal::DESTROY; 

    # .. 
} 
+0

感謝您的快速回復。此解決方案正在運行!但是'Devel :: Cover'並沒有檢測到這個分支案例: blib/lib/Horse.pm line | %|覆蓋範圍|分支 14 | 50 | T(綠色)| F(紅色)|如果$ self-> can('SUPER :: DESTROY') – mabe02

+0

你想要'DESTROY'返回'undef',還是一起刪除'DESTROY'? –

+2

@ mabe02要完全刪除該方法,只需要定位glob而不指定一個新的sub:'local * Animal :: DESTROY;'就足夠了。 – amon