Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^8: Moose and default values

by tobyink (Abbot)
on Feb 20, 2013 at 23:15 UTC ( #1019862=note: print w/ replies, xml ) Need Help??


in reply to Re^7: Moose and default values
in thread Moose and default values

With enough hacking you can make anything look declarative!

use v5.14; use strict; use warnings; # Ugly hack code # package MooseX::AttributeShouldIgnoreFalse { BEGIN { $INC{'MooseX/AttributeShouldIgnoreFalse.pm'} = __FILE__ }; use Sub::Exporter -setup => { exports => ['attribute_should_ignore_false'], groups => { default => ['attribute_should_ignore_false'], }, }; sub attribute_should_ignore_false { my @attrs = @_; my $meta = (scalar caller)->meta; $meta->add_around_method_modifier(BUILDARGS => sub { my $orig = shift; my $self = shift; my $parm = $self->$orig(@_); $parm->{$_} || delete $parm->{$_} for @attrs; $parm; }); } } # Lovely declarative code # package Foo { use Moose; use MooseX::AttributeShouldIgnoreFalse; has foo => (is => 'ro', default => 'whatever'); attribute_should_ignore_false 'foo'; } my $value = 'hello'; print Foo->new(foo => $value)->dump; $value = ''; print Foo->new(foo => $value)->dump;
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name


Comment on Re^8: Moose and default values
Download Code
Replies are listed 'Best First'.
Re^9: Moose and default values
by morgon (Deacon) on Feb 20, 2013 at 23:28 UTC
    Were getting here :-)

    Ideally I would want to declare everything at the attriute-level, e.g.:

    has foo => (is => "ro", default => { value => "whatever", when => "fal +se" });
    Can you do that as well?

    I am not so much interested in the feature itself, but it is interesting to see some examples of Moose-metaprogramming at work...

    Thanks!

      In this case what I'd suggest is a custom type constraint.

      use Moose::Util::TypeConstraints; subtype 'TrueStr', as 'Str', where { !!$_ }; coerce 'TrueStr', from 'Any', via { $_ || "whatever" }; has foo => (is => "ro", isa => "TrueStr", coerce => 1);

      Then any value which is not a TrueStr will be coerced into one via the code $_ || "whatever".

      Of course, this also applies to accessors, not just the constructor. (Not a problem for a read-only attribute though!) And also, it means that if you've got a bunch of attributes like this, each with different defaults, you need to define a type constraint for each one.

      The alternative - attribute metaprogramming - starts off seeming simple enough, but becomes more complicated when you start thinking about immutability. (Attribute metaprogramming can be a real bitch when it touches on immutability.)

      A compromise would be to hook has to automatically build per-attribute type constraints and coecions. I submitted a patch to MooseX::AttributeShortcuts for precisely this feature some months ago, but it was only partly accepted: per-attribute constraints are now supported, but not coercions.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1019862]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (15)
As of 2015-07-07 21:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (93 votes), past polls