2013-10-22 96 views
3

我在課堂上使用的方法調用命名參數,並想知道是否有以確保沒有未知參數傳遞最佳實踐。這是我在做什麼的Perl:命名參數驗證的最佳實踐

sub classmethod { 
    my $self = shift; 
    my %args = (
     "param1" => "default1", 
     "param2" => "default2", 
     @_ 
    ) 

    if (my @invalid = grep { !/^(param1|param2)$/ } keys %args) { 
     croak "received unknown arg(s) ".join(",", @invalid)." from ".caller(); 
    } 
} 

這是一個正確的方式前進,或可能會導致性能問題?

最佳, 馬庫斯

回答

5

你可以使用Params::Validate。另一種選擇是Params::Check

如果PARAMS是固定的,那麼它的最好的發展過程中,以驗證他們,有現場時關閉驗證的選項。

+1

我已經投票贊成這兩個模塊似乎是有用的驗證參數。我不會讓這是一個被接受的答案,因爲使用另一個模塊來檢查不需要的術語似乎有些矯枉過正。無論如何,感謝您的努力! – Marcus

1

有很多的方式來傳遞在Perl參數,和很多的方法來驗證他們(或沒有)。

如果您使用明確的默認習慣用法並且想要輕觸,那麼您可以檢查散列中的鍵數等於默認中的鍵數。獲取密鑰數量是一種快速操作,不依賴於散列表的大小或內容。如果「在」 @_的關鍵不在%default,然後%args將有更多的密鑰。

這對當前的解決方案的缺點是它不會告訴您哪個密鑰是意外的。

sub classmethod { 
    my $self = shift; 
    my %args = (
     param1 => "default1", 
     param2 => "default2", 
     @_ 
    ); 
    keys %args == 2 or croak "received unknown arg. args: " . join(", ", keys %args); 
} 

或者做這樣的事情,以避免在更改參數數量時更改數字。

sub classmethod { 
    my $self = shift; 
    my %default = (
     param1 => "default1", 
     param2 => "default2", 
    ); 
    my %args = (%default, @_); 

    keys %args == keys %default or croak 'unknown arg' . join(", ", keys %args); 
} 
+0

另請參見[如何指定可選子例程參數的默認值?](http://stackoverflow.com/q/29577085/2173773) –