2012-08-10 19 views
0

前段時間我有$SIG{WINCH}問題,因爲我加載了兩個模塊都使用$SIG{WINCH}Problems with $SIG{WINCH} when using it in a module。 現在我試圖重建這種情況,但是這次我在一個子程序中放入了一個模塊$SIG{WINCH}

use warnings; 
use strict; 
package My_Package; 
use Exporter 'import'; 
our @EXPORT = qw(choose); 

sub choose { 
    # ... 
    my $size_changed; 
    local $SIG{WINCH} = sub { $size_changed = 1; }; # edit: added "local" 
    while (1) { 
     my $c = getch(); 
     if ($size_changed) { 
      write_screen(); 
      $size_changed = 0; 
      next; 
     } 
     # ... 
    } 
} 

現在看起來它正在工作。 如果我以這種方式本地化$SIG{WINCH}還是在重建時忘記了某些東西,我可以省嗎?

+3

你實際上本地化了什麼嗎?你還沒有使用過「local」,「my」或「our」這些通常與這些東西相關的關鍵字。在Perl中,變量保持全局,除非另有聲明...您可能需要'local $ SIG {WINCH} = sub {$ size_changed = 1; };'但我可能是錯的。 – 2012-08-10 14:19:54

+0

我只是在瀏覽perlipc時想到,我應該廣告「本地」。 – 2012-08-10 16:40:09

回答

1

這是有效的,因爲您的代碼在設置信號處理程序後立即進入while循環,因此沒有其他代碼可以運行(或設置新的處理程序)。當while循環退出時,您的處理程序未設置,舊的將自動恢復,這要歸功於local

對於更具彈性的代碼,我會檢查一下現有的信號處理程序是否存在,然後調用它。否則,任何其他具有SIGWINCH處理程序的模塊將被破壞。例如。

my $orig_sigwinch = $SIG{WINCH}; 
local $SIG{WINCH} = sub { 
    $orig_sigwinch->() if $orig_sigwinch && ref $orig_sigwinch eq 'CODE'; 
    $size_changed = 1; 
} 

請注意,這並不考慮在$orig_sigwinch是一個函數名,而不是代碼引用的情況。

+0

爲什麼處理程序在while循環退出時未被設置,而不是在'choose'例程結束時? – 2012-08-20 15:58:44

相關問題