--- On Wed, 3/4/09, MORGUN Alexander <zuk...@ukr.net> wrote:

> From: MORGUN Alexander <zuk...@ukr.net>
> Subject: RFC: How to overcome potential problems with before?
> To: moose@perl.org
> Date: Wednesday, March 4, 2009, 12:12 PM
> Hello,  
>   
> I've seen a lot of bugs with before on attributes. The
> last one in HTML::FormBuilder :) What is the good practice
> to do that? Stop using before on attributes? Use direct
> value access? Personally, i think that lazy + default is
> good, but i see much people (including me) using before
> everywhere, because it is handy. 

If given more than one way to do a task I would try to use the most 
semantically meaningful approach, makes understanding the code easier.  If 
that's not clear then try whatever is easier.  In this case I would usually 
favor either coercion or the lazy_build option if I wanted an attribute that 
needed to either be default created, dependent on other attributes, or inferred 
from incomplete or tangential incoming information.  When I see lazy_build I 
know right away what the author was intending, since that feature was added 
specifically to address this need.  Method wrappers were created for more 
general functionality, but are often used as a more sane approach to how to 
override methods in parent or delagated classes.  I'd recommend something like:

class Test {
     has 'a' => (is=>'rw', lazy_build=>1);

     method _a {
       # return whatever you want 'a' to contain.
     } 
}


Personally I tend away from rw attributes lately unless it's for true entity 
style classes, since I find they can leave the class in inconsistent or 
unforseen states.  But I don't know your entire need.  If you could describe 
the logical goal here, maybe we could find a better way for you to do this.

See "http://search.cpan.org/~stevan/Moose/lib/Moose/Cookbook/Recipe9.pod"; for 
more on the lazy_build if you need a refresh.

John

>   
> #!/usr/bin/perl -w  
> use MooseX::Declare;  
>   
> class Test {  
>     has 'a' => (isa => 'Int', is
> => 'rw');  
>   
>     before a {  
>         $self->do_calculations;  
>     }  
>     method do_calculations {  
>         #after a lot of refactorings in some cases
> we check the $self->a  
>         $self->a;  
>     }  
> }  
>   
> my $t = Test->new(a=>2);  
> print $t->a;


      

Reply via email to