2011-03-06 38 views
5

我正在将传统应用程序转换为使用驼鹿(和催化剂)并且有以下问题。Perl Moose - 检查变量是否为驼鹿数据类型

如何确定穆斯用户输入的数据类型?

下面粗略的例子使用下面非常基本的“验证”方法'提交'多个查询并根据预期的表单域'id','name'和'email'验证数据。

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' => '[email protected]' 
       }, 
       { '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" } 
       }; 
    } 
} 

为了测试此代码,只需运行...

#!/usr/bin/perl 
use Moose; 
use CheckFields; 

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

1; 

是否有可能做这样的事情,你设置使用ISA设置为“任意” ...

has '_validate_field' => (is => 'rw', isa => 'Any'); 
变量

...然后测试具体类型如下?

$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 - 感谢你在百忙之中回复的时候,我是比较新的驼鹿让你使用MooseX :: PARAMS的::验证可能尽管不是我想要的,但尽管是最终的解决方案。我的意图是能够报告每个错误的特定领域,而不是整体报告验证失败。为此,我想我可以定义一个默认的,驼鹿友好的输入持有人isa设置为'任何'。然后'eval'(或其他)来查看数据是否符合特定类型(Int,Str或由我定义的一些自定义类型)。

我试图用“$ self-> validate_field-> meta-> isa('Int')...”引用的东西是沿着C/C++中的联合线的东西,其中一个变量可以是不同的类型 - 在这种情况下,我只是试图测试数据是否符合某种数据类型。

回答

2

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

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

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' => '[email protected]' 
      }, 
      { '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(); 

其他的方法,我可以看到的是,使对于数据的驼鹿类(包括验证这种方式),并检查是否实例可以在没有验证错误被创建。事情是这样的:

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 => '[email protected]'}, 
    { 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"; 
    }; 
} 
+0

感谢你在百忙之中回复的时候,我是比较新的驼鹿所以你MooseX的使用:: PARAMS ::验证很可能是最终解决方案虽然不是很什么,我寻找。 – user647248

+0

@ user647248 - 这里有两个注释。首先,您可以检查异常以找出哪些字段验证失败。其次,使用'MooseX :: Params :: Validate'概述的技术可以很容易地修改为单独检查值。 – bvr

+0

+1使用自定义类型测试项目的好方法。 –