Как я могу проверить типы перечисления в качестве аргументов подпрограммы Perl? - PullRequest
3 голосов
/ 25 июня 2009

Построение из Имеет ли Perl тип перечисления? , как я могу выполнить динамическую проверку типов (или статическую проверку типов, если это возможно при использовании 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

Ответы [ 3 ]

4 голосов
/ 25 июня 2009

Вот один из способов:

#!/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
3 голосов
/ 25 июня 2009

Я бы посоветовал вам использовать 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 есть модуль, который позволит вам иметь большой контроль над типами и значениями аргументов, но я не могу вспомнить его. Возможно, кто-то еще может.

2 голосов
/ 25 июня 2009
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 необходим для установки $ типов во время компиляции, чтобы он был доступен для оператора use.)

В Perl довольно распространено быть расслабленным относительно таких вещей; просто предположить, что функциям передаются числа там, где вы ожидаете числа и т. д. Но если вы хотите выполнить такую ​​проверку, вас может заинтересовать Params :: Validate .

...