3

建立Perl 有枚举类型吗?,我如何执行动态类型检查(或静态类型检查,如果使用严格能够这样做)我的子例程参数正在获取正确的枚举类型?

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
4

3 回答 3

4

这是一种方法:

#!/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
于 2009-06-25T11:07:21.103 回答
3

我建议您使用 Readonly (如引用问题中的建议)而不是常量。我建议使用两种可能的方法(取决于您使用的是 Perl 5.10 还是 5.8)。

最初,相同的代码:

use strict;
use warnings;
use Readonly;

Readonly my @phone_types = qw/HOME WORK/;

Perl 5.10:

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

Perl 5.8:

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

CPAN 上有一个模块可以让您对参数类型和值进行大量控制,但我一生都记不住它。也许别人可以。

于 2009-06-25T11:18:17.790 回答
2
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

(BEGIN 必须在编译时设置 $types 以便它可用于 use 语句。)

在 Perl 中,对这样的事情放松是很常见的;假设函数在您期望数字的地方传递数字等。但是如果您想做这种验证,您可能对Params::Validate感兴趣。

于 2009-06-25T16:07:57.483 回答