2011-12-27 3 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 под. Когда вы вызываете $self->{query} из create_uri, вы получаете доступ к запросу/attribute/called. Есть два решения:

1) Заменить $self->{query} с $self->query

2) Вместо использования around query используйте trigger опцию на атрибут, который вызывает функцию каждый раз, когда атрибут установлен. См. http://metacpan.org/pod/Moose.

+0

Спасибо! Я использовал первый вариант. , но получение успеха с помощью «тигров» тоже. – killzone

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