首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl Moose -检查变量是否为Moose数据类型

Perl Moose -检查变量是否为Moose数据类型
EN

Stack Overflow用户
提问于 2011-03-06 20:24:46
回答 1查看 2K关注 0票数 5

我正在将遗留应用程序转换为使用Moose (和催化剂),并有以下问题。

如何确定用户输入的驼鹿数据类型?

在下面的粗糙示例中,我使用下面最基本的“验证”方法“提交”多个查询,并根据预期的表单字段“id”、“name”和“email”验证数据。

代码语言:javascript
复制
use MooseX::Declare;
class CheckFields
{
    #has '_field' => ( is => 'rw', isa => 'Any' );

    # Fields on form and type to which they must match.
    method fields()
    {
        return [ { name => 'id',    type => 'Int' },
                 { name => 'name',  type => 'Str' },
                 { name => 'email', type => 'Email' }
               ];
    }

    # Dummy form posted requests.
    method queries()
    {
        return [ { 'id'    => 1,
                   'name'  => 'John Doe',
                   'email' => 'john@doe.net'
                 },
                 { 'id'    => 'John Doe',
                   'name'  => 1,
                   'email' => 'john.at.doe.net'
                 }
               ];
    }

    method validate_fields()
    {
        my $fields = $self->fields();

        # Loop through dummy form post requests
        foreach my $query ( @{ $self->queries } )
        {
            # Validate each field in posted form.
            foreach my $field ( @{ $fields } )
            {
                my $type = $field->{'type'};
                my $name = $field->{'name'};

                my $res = $self->validate->{ $type }( $query->{ $name} );
                print "$name is $res\n";
            }
            print "\n";
        }
    }

    # Very basic, slightly crude field validation.
    method validate()
    {
        return { 'Int'   => sub { my $val = shift; return $val =~ /^\d+$/ ? "ok" : "not ok" },
                 'Str'   => sub { my $val = shift; return $val =~ /^[a-zA-Z\s]+$/ ?"ok" : "not ok"  },
                 'Email' => sub { my $val = shift; return $val =~ /^(.+)\@(.+)$/ ?"ok" : "not ok"  }
               };
    }
}

要测试这段代码只需运行..。

代码语言:javascript
复制
#!/usr/bin/perl
use Moose;
use CheckFields;

CheckFields->new()->validate_fields();

1;

如果您设置一个变量,并将isa设置为“Any”,是否可以这样做?

代码语言:javascript
复制
has '_validate_field' => ( is => 'rw', isa => 'Any' );

对特定类型的...then测试如下?

代码语言:javascript
复制
$self->validate_field(1);
print $self->validate_field->meta->isa('Int') ? 'Int found' : 'Int not found';

$self->validate_field('ABC');
print $self->validate_field->meta->isa('Int') ? 'Int found' : 'Int not found';

提前谢谢你

编辑:@bvr -谢谢您抽出时间回复,我对Moose相对来说是个新手,所以您使用MooseX::Params::quite很可能是最终的解决方案,尽管不是我想要的。我的意图是能够报告每个错误的特定字段,而不是作为一个整体报告验证失败。为此,我想我可以定义一个默认的、对驼鹿友好的输入持有者,isa设置为'Any‘。然后查看数据是否符合特定类型(Int、Str或由我定义的自定义类型)。

我试图得到的“$self->validate_field->meta->isa(‘Int’).”引用类似于C/C++中的联合,其中变量可以是不同的类型--在这种情况下,我只是尝试测试数据是否符合特定的数据类型。

EN

回答 1

Stack Overflow用户

发布于 2011-03-06 20:35:49

我不确定我是否完全遵循了您问题的最后一部分,但是您的初始示例可以从使用MooseX::Params::Validate中受益。

编辑:,我编写了一些代码来评估我的建议。

代码语言:javascript
复制
use MooseX::Declare;
class CheckFields {

    use Moose::Util::TypeConstraints;
    use MooseX::Params::Validate;
    use Try::Tiny;
    use Data::Dump qw(pp);

    subtype 'Email' 
        => as 'Str' 
        => where {/^(.+)\@(.+)$/};

    method fields() {
        return [
            id    => {isa => 'Int'},
            name  => {isa => 'Str'},
            email => {isa => 'Email'},
        ];
    }

    method queries() {
        return [
            {   'id'    => 1,
                'name'  => 'John Doe',
                'email' => 'john@doe.net'
            },
            {   'id'    => 'John Doe',
                'name'  => 1,
                'email' => 'john.at.doe.net'
            }
        ];
    }

    method validate_fields() {
        my $fields = $self->fields();

        foreach my $query (@{$self->queries}) {
            try {
                my (%params) = validated_hash([%$query], @{$fields});
                warn pp($query) . " - OK\n";
            }
            catch {
                warn pp($query) . " - Failed\n";
            }
        }
    }
}

package main;

CheckFields->new()->validate_fields();

我看到的其他方法是为数据创建一个Moose类(通过这种方式进行验证),并检查是否可以在没有验证错误的情况下创建实例。就像这样:

代码语言:javascript
复制
use MooseX::Declare;
class Person {
    use Moose::Util::TypeConstraints;

    subtype 'Email'
        => as 'Str'
        => where {/^(.+)\@(.+)$/};

    has id    => (is => 'ro', isa => 'Int');
    has name  => (is => 'ro', isa => 'Str');
    has email => (is => 'ro', isa => 'Email');
}

package main;

use Try::Tiny;
use Data::Dump qw(pp);

my @tests = (
    { id => 1,          name => 'John Doe', email => 'john@doe.net'},
    { id => 'John Doe', name => 1,          email => 'john.at.doe.net'},
);

for my $query (@tests) {
    try {
        my $person = Person->new(%$query);
        warn pp($query) . " - OK\n";
    }
    catch {
        warn pp($query) . " - Failed\n";
    };
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5213143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档