Eu prefiro deixar minhas validacoes juntos com as definicoes dos atributos
dos meus objetos, pois provavelmente eu vou validar um objeto antes de
fazer algo com ele.
Então eu faco o seguinte (o exemplo abaixo é para exemplificar atraves da
analise do mesmo, ele não irá compilar):

Em resumo:
1. defino os campos dentro de um hash, juntos com as validacoes
2. faco um loop para adicionar (com moose) cada campo na classe
3. defino um metodo salvar e esse metodo salvar vai verificar se o atributo
tem alguma validacao que deve ser executada

Entao eu termino com algo assim:

package My::Class;
use Moose;

#meta definicao dos meus atributos.. fica dentro de um hash... os atributos
ainda nao foram declarados
#nelas residem as validacoes, coerce, sql etc tudo que é simples e
relacionado a esse campo
#consigo incluir por exemplo um array com items para eu validar antes de
salvar, etc
#ex
my $attrs = {
    'preco' => {
        # isa => 'Int', #opcional
        req => 1,
        validation_regex => '(\d+)', # vou usar isso antes do metodo save
        coerce => sub { #   Vai executar tambem isso antes do save
            my ( $self, $value ) = @_;
            $value =~ s|^ +| +\$|g;
            $value =~ s|(.+)(,\|\.)00\$|$1|gi;
            $value =~ s|\D||gi;
            return $value;
        },
        sql =>
          {
            "type"       => "integer",
            "null_value" => 0
          },
        validacao_extra => [
          {
            rotulo => 'Verifica se contem numeros na mensagem',
            validacao => sub {
              my ( $campo ) = @_;
              return 1 if "valido" eq "valido";
              return 0;
            },
            msg_erro => "Tem erro nesse campo"
          }
          ,
          .... e depois adicionar o "validacao_extra" la ao final no
before_save
          ... e pronto...

        ]
    },
    'url' => {
        req              => 1,
        validation_regex => '^http',
        sql          => {
            type    => 'string',
            "index" => 'not_analyzed',
        }
    },

    'idade' => {
        req              => 1,
        validation_regex => '(\d+)',
        sql          => {
            "type"       => "integer",
            "null_value" => 0
        },
    },
};

# declara cada atributo para esta classe
foreach my $attr ( keys $attrs ) {
    #Mete o has dentro do foreach pra declarar cada chave dos meus $attrs
    has $attr => (
        is => 'rw', #podia vir do meu config la de cima ne...
        ( exists $attrs->{$attr}->{default} )
        ? (
            default => $attrs->{$attr}->{default}
          )
        : (),
    );
}

#coerce nos valores, é usado antes do metodo save... mas pode muito bem
usar o coerce do moo(u|se)
sub coerce {
    my ($self) = @_;
    foreach my $attr ( keys %$attrs ) {
        if ( exists $attrs->{$attr}->{coerce} && defined $self->$attr ) {
            $self->$attr(
                $attrs->{$attr}->{coerce}->( $self, $self->$attr ) );
        }
    }
}

#valida antes de salvar
#pode por exemplo verificar se foi setado e executar o $attrs->{ $attr }->{
validation_regex }, etc
sub validate {
    my ($self) = @_;
    foreach my $attr ( keys $attrs ) {
        return 0
          if exists $attrs->{$attr}->{req}
              and $attrs->{$attr}->{req} == 1
              and !defined $self->$attr;
         if ( exists $attrs->{ $attr }->{ validation_regex } ) {
            //valida a bagaca
            //pode ler de $self, ou receber o valor como parametro da sub
validate, etc
         }
    }
    return 1;
}

#before save...
before 'save' => sub {
    my ($self) = @_;
    $self->coerce();
};

#save somente se validate
sub save {
    my ($self) = @_;
    next unless $self->validate();
}



abs,

Hernan










2013/9/3 Blabos de Blebe <[email protected]>

> Na verdade foi até coincidência o Solli tocar no assunto, pq assim como
> mapas, eu ia perguntar isso pra vcs em breve.
>
>
> 2013/9/3 Blabos de Blebe <[email protected]>
>
>> > Blabos, e se você tiver 2 formulários na mesma página, por exemplo, um
>> de login e um de cadastro ? Vai ter que melhorar na gambi né ? heheheheheh
>>
>> Correto.
>>
>> > Se mudar o nome do campo entao… chora hehehe
>>
>> Correto denovo.
>>
>> > Marcar o campo errado em vermelho vai precisar de mais gambi :D
>>
>> Mais ou menos. Eu uso uma alternativa, no exemplo. Mas sim, é melhor
>> marcar o campo com vermelho.
>>
>> > Tem muitas vantagens usar o Data::Manager
>>
>> Correto denovo.
>>
>> O porém é que o meu exemplo é exatamente específico. Um form, quatro
>> campos.
>>
>> Não to dizendo que nao vou usar o Data::Manager, ou alguma solução
>> parecida. Só nao vou usar nessa semana :)
>>
>> As soluções apresentadas são apenas o mais pá-pow que dá pra fazer com
>> *a* hard-restriction desse sprint: tempo; e uma soft-restriction:
>> Data::Manager é novo pra mim.
>>
>> Depois eu refatoro. Tá previsto isso.
>>
>> Tá pronto x Tá bom.
>>
>> No meu caso nesse momento, tá pronto é mandatório. Quem me conhece sabe o
>> quanto eu gosto de gambiarra e o quanto tá custando esse tá pronto.
>>
>> :)
>>
>> []'s
>>
>>
>>
>>
>>
>> 2013/9/3 Lucas Oliveira <[email protected]>
>>
>>>
>>> Blabos, e se você tiver 2 formulários na mesma página, por exemplo, um
>>> de login e um de cadastro ? Vai ter que melhorar na gambi né ? heheheheheh
>>>
>>> Se mudar o nome do campo entao… chora hehehe
>>>
>>> Se precisar fazer um "pirulito" para importar para a base a validação
>>> não é aproveitável… esqueçe
>>>
>>> Marcar o campo errado em vermelho vai precisar de mais gambi :D
>>>
>>> Tem muitas vantagens usar o Data::Manager
>>>
>>>
>>> Em 03/09/2013, às 18:30, Blabos de Blebe <[email protected]> escreveu:
>>>
>>> Opa,
>>>
>>> O meu caso é muito simples (pequeno) e o meu tempo é curto. O que foi
>>> mais rápido pra mim foi essa tosqueria aqui:
>>>
>>> No controller:
>>>
>>> ...
>>> my $errors  = [];
>>>
>>> ## not null
>>> foreach my $field ( keys %{$fields} ) {
>>>     push @{$errors}, 'empty_' . $field
>>>       unless $fields->{$field};
>>> }
>>>
>>> ## unique
>>> foreach my $field (qw{ username email }) {
>>>     push @{$errors}, 'already_' . $field
>>>       if $rs_user->find( { $field => $fields->{$field} } );
>>> }
>>>
>>> ## invalid email
>>> push @{$errors}, 'invalid_email'
>>>   unless Email::Valid->address( $fields->{email} );
>>>
>>> if ( @{$errors} > 0 ) {
>>>     $c->stash->{user}   = $fields;
>>>     $c->stash->{errors} = $errors;
>>>     return;
>>> }
>>> ...
>>>
>>> No template:
>>>
>>>     [% IF errors.size > 0 %]
>>>         <div data-alert class="alert-box alert">
>>>             [% FOREACH error IN errors %]
>>>                 [% msg_block = 'msg_' _ error %]
>>>                 [% PROCESS $msg_block %]<br>
>>>             [% END %]
>>>             <a href="#" class="close">&times;</a>
>>>         </div>
>>>     [% END %]
>>> ...
>>>
>>> [% BLOCK msg_empty_full_name %]
>>>     Você precisa preencher o seu nome completo.
>>> [% END %]
>>>
>>> [% BLOCK msg_empty_username %]
>>>     Você precisa preencher o seu username.
>>> [% END %]
>>> ...
>>>
>>>
>>>
>>> Deve ter formas mais inteligentes de fazer isso, mas no momento, a mais
>>> inteligente pra mim, é a que eu consigo fazer mais rápido. Esse é meu
>>> "único" form.
>>>
>>> []'s
>>>
>>>
>>> 2013/9/3 Solli Honorio <[email protected]>
>>>
>>>> Blabos, o que você está imaginando para validar ? Estilo old-school com
>>>> um encadeamento de if ? Dispatch table ? NDA ?
>>>>
>>>> Abraços,
>>>>
>>>> Solli Honorio
>>>>
>>>>
>>>> Em 3 de setembro de 2013 16:35, Blabos de Blebe <[email protected]>escreveu:
>>>>
>>>> Em alguns casos, complexidade é um pouco ponto de vista.
>>>>>
>>>>> Acho que entendi a abordagem do mantovani, mas pro meu caso
>>>>> específico, acho que é também o overhead, já que eu só valido 4 campos em
>>>>> uma situação eventual. Estou cogitando nem usar o Data::Manager.
>>>>>
>>>>> Se fosse um cazilhao de campos sendo validados constantemente, acho
>>>>> que valeira a pena.
>>>>>
>>>>> Mantovani, cuidado pra não ficar aparafusando pregos, certo!?
>>>>>
>>>>> []'s
>>>>>
>>>>>
>>>>> 2013/9/3 Solli Honorio <[email protected]>
>>>>>
>>>>>> Sério mesmo Mantovani que vc acha que um sistema de fila é a solução
>>>>>> para eu validar se todos os campos de um formulário estão dentro do
>>>>>> aguardado para trabalhar no  banco de dados ?
>>>>>>
>>>>>> Mantovani, só posso dizer que estou orgulhoso de você... vejo que
>>>>>> você terá um excelente futuro na industria de tecnologia (coisa que eu 
>>>>>> não
>>>>>> tive), pois este é bem o comportamento dos vendedores de TI. Você está
>>>>>> agregando complexidade numa lugar que estou tentando agregar simplicidade
>>>>>> :D !!!
>>>>>>
>>>>>> Abraços,
>>>>>>
>>>>>> Solli Honorio
>>>>>>
>>>>>>
>>>>>>
>>>>>> Em 3 de setembro de 2013 14:58, Daniel de Oliveira Mantovani <
>>>>>> [email protected]> escreveu:
>>>>>>
>>>>>> 2013/9/3 Solli Honorio <[email protected]>:
>>>>>>> > Lucas,
>>>>>>> >
>>>>>>> > Obrigado pelo retorno. Ontem a noite estudei o código do
>>>>>>> Data::Manager e ví
>>>>>>> > que realmente não rola fazer o que eu estava querendo fazer
>>>>>>> (passar uma
>>>>>>> > pilha de mensagem e receber de acordo com o contexto) e ai estou
>>>>>>> > encaminhando para a mesma solução que você.
>>>>>>>
>>>>>>> " o que eu estava querendo fazer (passar uma pilha de mensagem e
>>>>>>> receber de acordo com o contexto)"
>>>>>>>
>>>>>>> Shonorio, repetindo o AMQP se encaixa perfeitamente. Eu sugiro que
>>>>>>> você leia o link que eu te enviei. Se um serviço na sua máquina vai
>>>>>>> te
>>>>>>> poupar centenas de linhas de código, talvez nessa situação, nesse
>>>>>>> contexto obscuro no qual não foi definido pelo interlocutor seja uma
>>>>>>> boa.
>>>>>>>
>>>>>>> Se você acha que isso é demais para você, eu sinto muito que alguém
>>>>>>> com pelo menos 15/20 anos de experiência ainda não saiba formular uma
>>>>>>> pergunta. Perguntas genéricas, respostas genéricas. E ainda acho
>>>>>>> extremamente desnecessário o seu ataque gratuito, mas se você ainda
>>>>>>> não percebeu isso afasta as pessoas da lista.
>>>>>>>
>>>>>>> >
>>>>>>> > Como vc faz com o I18N ?
>>>>>>> >
>>>>>>> > O Renato Cron publicou um 'template'  (
>>>>>>> https://github.com/AwareTI/MyApp )
>>>>>>> > de como eles estão utilizando o Data::Manager. Estudei o código e
>>>>>>> achei
>>>>>>> > engenhoso, mas ainda quero manter um melhor controle do ResultSet
>>>>>>> porquê
>>>>>>> > quero devolver uma estrutura mais complexa de informação.
>>>>>>> >
>>>>>>> > Abraços,
>>>>>>> >
>>>>>>> > Solli Honorio
>>>>>>> >
>>>>>>> >
>>>>>>> >
>>>>>>> > 2013/9/3 Lucas Oliveira <[email protected]>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> Normalmente eu uso sempre com I18N mas da pra quebrar o galho
>>>>>>> assim
>>>>>>> >>
>>>>>>> >> <code>
>>>>>>> >> #!/usr/bin/env perl
>>>>>>> >>
>>>>>>> >> use common::sense;
>>>>>>> >> use Data::Manager;
>>>>>>> >> use Data::Verifier;
>>>>>>> >>
>>>>>>> >> my %msg_data = (
>>>>>>> >>    missing_name_last => 'Nao foi informado o campo name_last, seu
>>>>>>> idiota
>>>>>>> >> !',
>>>>>>> >> );
>>>>>>> >>
>>>>>>> >> sub messages { $msg_data{$_[0]} || $_[0] }
>>>>>>> >>
>>>>>>> >> my $dm = Data::Manager->new;
>>>>>>> >> my $dv = Data::Verifier->new(
>>>>>>> >>     filters => [ qw(trim) ],
>>>>>>> >>         profile => {
>>>>>>> >>             name_first => {
>>>>>>> >>                 required => 1,
>>>>>>> >>                 type     => 'Str',
>>>>>>> >>                 filters  => [ qw(collapse) ]
>>>>>>> >>             },
>>>>>>> >>             name_last => {
>>>>>>> >>                 required => 1,
>>>>>>> >>                 type     => 'Str',
>>>>>>> >>                 filters  => [ qw(collapse) ]
>>>>>>> >>             },
>>>>>>> >>             age  => {
>>>>>>> >>                 type        => 'Int'
>>>>>>> >>             },
>>>>>>> >>             sign => {
>>>>>>> >>                 required    => 1,
>>>>>>> >>                 type        => 'Str'
>>>>>>> >>             }
>>>>>>> >>         }
>>>>>>> >>     );
>>>>>>> >>
>>>>>>> >> $dm->set_verifier( name => $dv );
>>>>>>> >> $dm->verify( name => { name_first => 'Solli' });
>>>>>>> >>
>>>>>>> >> if (!$dm->success) {
>>>>>>> >>    print &messages( $_->msgid ).$/
>>>>>>> >>       foreach (@{ $dm->messages->messages });
>>>>>>> >> }
>>>>>>> >> </code>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> Em 02/09/2013, às 11:10, Solli Honorio <[email protected]>
>>>>>>> escreveu:
>>>>>>> >>
>>>>>>> >> Pessoal,
>>>>>>> >>
>>>>>>> >> Estou tentando configurar uma mensagem padronização no
>>>>>>> Data::Manager, mas
>>>>>>> >> não está funcionando. Alguém aqui já utilizou o Data::Manager
>>>>>>> para saber se
>>>>>>> >> é possível fazer isto que eu quero ?
>>>>>>> >>
>>>>>>> >> O código abaixo, estou criando uma mensagem e adicionando no
>>>>>>> Data::Manger,
>>>>>>> >> porquê eu imaginei que quando ocorrer o problema dentro do escopo
>>>>>>> e msgid,
>>>>>>> >> eu teria o texto padronizado, mas o que estou recebendo é mais
>>>>>>> uma pilha de
>>>>>>> >> mensagem, mesmo quando não existe o erro.
>>>>>>> >>
>>>>>>> >> <code>
>>>>>>> >> #!/usr/bin/env perl
>>>>>>> >> use common::sense;
>>>>>>> >> use Data::Manager;
>>>>>>> >> use Data::Verifier;
>>>>>>> >> use Data::Printer;
>>>>>>> >>
>>>>>>> >> my $msg = Message::Stack->new;
>>>>>>> >> $msg->add({
>>>>>>> >>     msgid   => 'missing_name_last',
>>>>>>> >>     level   => 'error',
>>>>>>> >>     scope   => 'name1',
>>>>>>> >>     subject => 'name_last',
>>>>>>> >>     text    => 'Não foi informado o campo name_last, seu idiota
>>>>>>> !'} );
>>>>>>> >>
>>>>>>> >> my $dm = Data::Manager->new( { messages => $msg } );
>>>>>>> >> my $dv = Data::Verifier->new(
>>>>>>> >>     filters => [ qw(trim) ],
>>>>>>> >>         profile => {
>>>>>>> >>             name => {
>>>>>>> >>                 required => 1,
>>>>>>> >>                 type     => 'Str',
>>>>>>> >>                 filters  => [ qw(collapse) ]
>>>>>>> >>             },
>>>>>>> >>             age  => {
>>>>>>> >>                 type        => 'Int'
>>>>>>> >>             },
>>>>>>> >>             sign => {
>>>>>>> >>                 required    => 1,
>>>>>>> >>                 type        => 'Str'
>>>>>>> >>             }
>>>>>>> >>         }
>>>>>>> >>     );
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> };
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> $dm->set_verifier('name1', $verifier);
>>>>>>> >> $dm->verify('name1', { name_last => 'Honorio', name_first =>
>>>>>>> 'Solli' });
>>>>>>> >>
>>>>>>> >> my $results = $dm->get_results('name1');
>>>>>>> >> my $stack   = $dm->messages_for_scope('name1');
>>>>>>> >>
>>>>>>> >> say $results->success;
>>>>>>> >>
>>>>>>> >> say "Is invalid name_first ", $results->is_invalid('name_first');
>>>>>>> >> say "Is invalid name_last ",  $results->is_invalid('name_last');
>>>>>>>  # yes
>>>>>>> >>
>>>>>>> >> say "Is missing name_first ", $results->is_missing('name_first');
>>>>>>> # no
>>>>>>> >> say "Is missing is_missing ", $results->is_missing('name_last');
>>>>>>> # yes
>>>>>>> >>
>>>>>>> >> say "Missing count ", $results->missing_count;
>>>>>>> >>
>>>>>>> >> say "Count : ",  $stack->count ;
>>>>>>> >> p $stack->get_message( 0 );
>>>>>>> >> p $stack->get_message( 1 );
>>>>>>> >>
>>>>>>> >> </code>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> --
>>>>>>> >> "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>> >> =begin disclaimer
>>>>>>> >>   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> >> SaoPaulo-pm mailing list: [email protected]
>>>>>>> >> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> >> =end disclaimer
>>>>>>> >>
>>>>>>> >>
>>>>>>> >>
>>>>>>> >> =begin disclaimer
>>>>>>> >>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> >>  SaoPaulo-pm mailing list: [email protected]
>>>>>>> >>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> >> =end disclaimer
>>>>>>> >>
>>>>>>> >
>>>>>>> >
>>>>>>> >
>>>>>>> > --
>>>>>>> > "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>> >
>>>>>>> > =begin disclaimer
>>>>>>> >    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>> >  SaoPaulo-pm mailing list: [email protected]
>>>>>>> >  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> > =end disclaimer
>>>>>>> >
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> -dom
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> Daniel de Oliveira Mantovani
>>>>>>> Business Analytic Specialist
>>>>>>> Perl Evangelist /Astrophysics hobbyist.
>>>>>>> +55 11 9 8538-9897
>>>>>>> XOXO
>>>>>>> =begin disclaimer
>>>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>>  SaoPaulo-pm mailing list: [email protected]
>>>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> =end disclaimer
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> "o animal satisfeito dorme". - Guimarães Rosa
>>>>>>
>>>>>> =begin disclaimer
>>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>  SaoPaulo-pm mailing list: [email protected]
>>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>> =end disclaimer
>>>>>>
>>>>>>
>>>>>
>>>>> =begin disclaimer
>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>  SaoPaulo-pm mailing list: [email protected]
>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>> =end disclaimer
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> "o animal satisfeito dorme". - Guimarães Rosa
>>>>
>>>> =begin disclaimer
>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>  SaoPaulo-pm mailing list: [email protected]
>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>> =end disclaimer
>>>>
>>>>
>>> =begin disclaimer
>>>   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>> SaoPaulo-pm mailing list: [email protected]
>>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>>
>>>
>>> =begin disclaimer
>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>  SaoPaulo-pm mailing list: [email protected]
>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>>
>>
>
> =begin disclaimer
>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>  SaoPaulo-pm mailing list: [email protected]
>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>
=begin disclaimer
   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
 SaoPaulo-pm mailing list: [email protected]
 L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
=end disclaimer

Responder a