Perl OO 包中简化的默认参数处理
这是我所拥有的重要子集:
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});
}
问题是他们可以指定我的选项列表之外的内容,或者发送散列而不是散列引用,或者标量,或者 undef,或者许多其他可能导致崩溃的方式。
我确信有一种更优雅的方法来处理这个问题。
我似乎记得一些使用 ref() 的代码,如果没有传入任何内容,则不会崩溃。
Here is the important subset of what I have:
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.
}
So then I can call it like so:
$op->logger({message => 'Some message'});
So if any of my parameters are missing, they get the defaults I've specified in the %def hash. If a required parameter is missing, I die.
The basis of it is I overload the def hash with what the user specified with this.
if ( my $ref = shift ) {
%opt = (%def, %{$ref});
}
Problem with this is they could specify things outside my list of options, or send in a hash instead of a hash ref, or a scalar, or undef, or many other ways this could blow up.
I'm sure there is a more elegant way to handle this.
I seem to recall some code using ref() that didn't blow up if nothing was passed in.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Method::Signatures 正是您所寻找的for and 非常优雅:
签名中的冒号指定命名参数(作为哈希传递)。
$message
后面的感叹号使其成为必需。Method::Signatures does precisely what you're looking for and is so very elegant :
The colons in the signature designate named parameters (passed as a hash). The exclamation mark following
$message
makes it required.处理这个问题的优雅方式都可以方便地捆绑在 Moose 中,如果 Moose 对你来说太重的话,甚至可以使用 Mouse 或 Moo。
The elegant way of handling this is all conveniently bundled for you in Moose, or even Mouse or Moo if Moose is too heavy for you.
我想我会做类似的事情。毫无疑问,尽管有大量 CPAN 模块可以使这一切变得更简单。
I think I'd do something like that. Although there are, no doubt, plenty of CPAN modules that make this simpler.