简体   繁体   English

如何验证枚举类型为Perl子例程参数?

[英]How can I validate enum types as Perl subroutine arguments?

Building off Does Perl have an enumeration type? 建立关闭Perl是否具有枚举类型? , how can I perform dynamic type checking (or static type checking if use strict is able to do so) that my subroutine argument is getting the right type of enum? ,如何执行动态类型检查(或静态类型检查,如果use strict能够这样做)我的子例程参数是否获得正确的枚举类型?

package Phone::Type;

use constant {
    HOME => 'Home',
    WORK => 'Work',
};

package main;

sub fun
{
    my ($my_phone_type_enum) = @_;
    # How to check my_phone_type_enum, is either Phone::Type->HOME or Phone::Type->WORK or ... but not 'Dog' or 'Cat'?
}

fun(Phone::Type->HOME); # valid
fun(Phone::Type->WORK); # valid
fun('DOG');             # run-time or compile time error

Here is one way: 这是一种方式:

#!/usr/bin/perl

package Phone::Type;

use strict;
use warnings;

use constant {
    HOME => 'Home',
    WORK => 'Work',
};

package main;

use strict;
use warnings;

sub fun {
    my ($phone_type) = @_;
    Phone::Type->can( $phone_type )
        or die "'$phone_type' is not valid\n";
}

fun('HOME'); # valid
fun('WORK'); # valid
fun('DOG');  # run-time or compile time error
__END__

C:\Temp> dfg
'DOG' is not valid

I would suggest that you use Readonly (as suggested in the referenced question) rather than constant. 我建议您使用Readonly(如引用的问题中所建议的)而不是常量。 I'd suggest on of two possible approaches (depending on if you are using Perl 5.10 or 5.8). 我建议采用两种可能的方法(取决于你使用的是Perl 5.10还是5.8)。

Initially, the same code: 最初,相同的代码:

use strict;
use warnings;
use Readonly;

Readonly my @phone_types = qw/HOME WORK/;

Perl 5.10: Perl 5.10:

sub fun
{
   my $type = shift;
   die "Invalid phone type: $type" unless $type ~~ @phone_types;
   # ...
}

Perl 5.8: Perl 5.8:

sub fun
{
   my $type = shift;
   die "Invalid phone type: $type" unless grep { $_ eq $type} @phone_types;
   # ...
}

There is a module on CPAN which will allow you to have a great deal of control over argument types and values but I can't for the life of me remember it. CPAN上有一个模块可以让你对参数类型和值有很大的控制权,但我不能记住它。 Perhaps someone else can. 也许其他人可以。

package Phone::Type;

my $types;
BEGIN {
    $types = {
        HOME => 'Home',
        WORK => 'Work',
    };
}
use constant $types;

sub is_phone_type {
    my ($type) = @_;
    return exists $types->{$type};
}

package main;
use Carp ();

sub fun
{
    my ($my_phone_type_enum) = @_;
    Phone::Type::is_phone_type( $my_phone_type_enum)
        or Carp::croak "Invalid type $my_phone_type_enum";
}

fun(Phone::Type->HOME); # valid
fun(Phone::Type->WORK); # valid
fun('DOG');             # run-time or compile time error

(The BEGIN is necessary to set $types at compile time so that it's available to the use statement.) (BEGIN是在编译时设置$ types所必需的,因此它可用于use语句。)

It's fairly common in Perl to be relaxed about things like this; 在Perl中,对这样的事情放松是很常见的; to just assume that functions are passed numbers where you expect numbers, etc. But if you want to do this kind of validation, you may be interested in Params::Validate . 假设函数是传递数字,你期望数字,等等。但如果你想做这种验证,你可能会对Params :: Validate感兴趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM