Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl OO包中简化的默认参数处理_Perl_Oop_Perl Module - Fatal编程技术网

perl OO包中简化的默认参数处理

perl OO包中简化的默认参数处理,perl,oop,perl-module,Perl,Oop,Perl Module,以下是我拥有的重要部分: sub logger { my $self = shift; my %def = ( type => $self->{options}{name}, severity => 1, date => $self->now(), message => '' ); my %opt = %def; if ( my $ref = shi

以下是我拥有的重要部分:

sub logger {
    my $self = shift;
    my %def =  (
        type => $self->{options}{name}, 
        severity => 1,
        date => $self->now(),
        message => ''  
    );
    my %opt = %def;
    if ( my $ref = shift ) {
        %opt = (%def, %{$ref});
    }
    croak('message is a required option') if $opt{message} eq '';
    warn($opt{type} . ': ' . $opt{message} . "\n") if ( $self->{_verbose} );
    # Do some other interesting things.
}
那么我可以这样称呼它:

$op->logger({message => 'Some message'});
因此,如果我的任何参数丢失,它们将获得我在%def散列中指定的默认值。如果缺少必需的参数,我就死了

其基础是我用用户指定的内容重载def散列

    if ( my $ref = shift ) {
        %opt = (%def, %{$ref});
    }
问题是他们可能会指定我的选项列表之外的内容,或者发送一个散列而不是散列引用,或者标量,或者未定义,或者其他许多可能会爆炸的方式

我相信有一种更优雅的方式来处理这个问题。

我似乎还记得一些使用ref()的代码,如果没有传递任何信息,这些代码就不会爆炸。

处理这些问题的优雅方式在Moose中非常方便,如果Moose对您来说太重,甚至可以使用鼠标或Moo。

完全符合您的要求,非常优雅:


签名中的冒号指定命名参数(作为散列传递)。
$message
后面的感叹号是必需的。

我想我应该这样做。尽管毫无疑问,有很多CPAN模块使这变得更简单

sub logger {
    my $self = shift;

    # Set $ref to an empty hash ref if it's not given.
    # This makes a lot of later code far simpler
    my $ref = shift || {};

    # Check you have a hash ref
    unless (ref $ref eq 'HASH') {
        die "Argument to logger must be a hash ref";
    }

    my %def =  (
        type => $self->{options}{name}, 
        severity => 1,
        date => $self->now(),
        message => '',
    );


    my %opt = (%def, %$ref);

    # Now check we only have valid options. Assume that all valid
    # keys are in %def
    foreach (keys %opt) {
        delete $opt{$_} unless exists $def{$_};
    }

    croak('message is a required option') if $opt{message} eq '';
    warn($opt{type} . ': ' . $opt{message} . "\n") if ( $self->{_verbose} );
    # Do some other interesting things.
}

实际上,我采用了MooseX::Method::Signatures的方式,但是你得到了勾号,因为你给出了一个链接和一个示例,所以你引导我找到了它。谢谢。Groovy虽然
Method::Signatures
Moose
兼容,并且支持
Moose
的类型约束。另请参见同一发行版中的
Method::Signatures::Modifiers
sub logger {
    my $self = shift;

    # Set $ref to an empty hash ref if it's not given.
    # This makes a lot of later code far simpler
    my $ref = shift || {};

    # Check you have a hash ref
    unless (ref $ref eq 'HASH') {
        die "Argument to logger must be a hash ref";
    }

    my %def =  (
        type => $self->{options}{name}, 
        severity => 1,
        date => $self->now(),
        message => '',
    );


    my %opt = (%def, %$ref);

    # Now check we only have valid options. Assume that all valid
    # keys are in %def
    foreach (keys %opt) {
        delete $opt{$_} unless exists $def{$_};
    }

    croak('message is a required option') if $opt{message} eq '';
    warn($opt{type} . ': ' . $opt{message} . "\n") if ( $self->{_verbose} );
    # Do some other interesting things.
}