3

構築Perlには列挙型がありますか?、サブルーチン引数が正しい型の列挙型を取得していることを動的型チェック(または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
4

3 に答える 3

4

これが1つの方法です:

#!/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

定数ではなく、(参照されている質問で提案されているように)読み取り専用を使用することをお勧めします。私は2つの可能なアプローチのうちの1つを提案します(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は、useステートメントで使用できるようにコンパイル時に$ typesを設定するために必要です。)

Perlでは、このようなことについてリラックスするのはかなり一般的です。関数には、数値などが期待される数値が渡されると想定します。ただし、この種の検証を行う場合は、Params::Validateに関心があるかもしれません。

于 2009-06-25T16:07:57.483 に答える