2011-12-27 78 views
1

我需要过滤传递给属性“查询” 的“字符串”,并使用过滤的值创建一个URL。moose perl方法修饰符

我的代码

package Search; 

use Any::Moose; 

has query => qw{ is ro isa Str required 1 }; 

# my method modifiers 
around 'query' => sub { 
    my $orig = shift; 
    my $self = shift; 

    my $content = $self->$orig(@_); 

    # simple filter 
    $content =~ s{[^\w\-\s]}{}gi; 

    return $content; 
}; 

sub create_uri { 
    my $self = shift; 
    my $uri = "http://localhost/search/".$self->{query}; 
    return $uri; 
}; 
1; 

package main; 
my $obj = Search->new({ 
    query => '[email protected]#$%#%#@&-**[email protected]@#%!', 
}); 

print $obj->query."\n"; 

print $obj->create_uri."\n"; # BAD 

输出这里:

print $search->query; 

FOO酒吧,符合市场预期。

当我打电话 “create_uri”

print $search->create_uri; 

输出:

http://localhost/search/[email protected]# $%#%#@ & - **吧@@#%!

“查询”完全脏! 如何解决这个问题?

回答

0

当您致电print $obj->query时,您正在调用/子程序/被叫查询,该查询调用您的around子。当您从create_uri内调用$self->{query}时,您可以访问/ attribute/called查询。解决办法有两个:

1)更换$self->{query}$self->query

2)而不是使用around query的,请使用属性,每个属性设置时它调用一个函数的trigger选项。有关信息,请参阅http://metacpan.org/pod/Moose

+0

谢谢! 我使用了第一个选项。 ,但使用“tiggers”也获得成功。 – killzone 2011-12-27 13:21:23

2

一对夫妇更多的途径中为您探索:

  1. 使用在类中BUILDARGS方法之前它被分配到施工的属性清理查询字符串。

    sub BUILDARGS { 
        my $type = shift; 
        my $args = ref $_[0] eq 'HASH' ? shift : {@_}; 
        $args->{query} =~ s{[^\w\-\s]}{}gi; 
        return $args; 
    } 
    
  2. 使用类型强制。

    subtype 'SafeStr', as 'Str', where {!/[^\w\-\s]/}; 
    
    coerce 'SafeStr', from 'Str', via { 
        my $str = $_; 
        $str =~ s/[^\w\-\s]//gi; 
        return $str; 
    }; 
    
    has 'query' => (
        is => 'ro', 
        isa => 'SafeStr', 
        required => 1, 
        coerce => 1, 
    ); 
    
+0

谢谢!这两种解决方案工作得很好。 我相信使用“胁迫”将效果最好。 我会通过使用“胁迫”而不是“触发器”获得一些收益? 'has query => qw {is ro isa Str required 1},trigger => \&_ filter_query;' – killzone 2011-12-28 16:12:07