On 29/01/11 07:23, Octavian Rasnita wrote:
Hi,

I want to use some attributes that get a default value when they are not sent 
as constructor's parameters and also when they are sent as constructor 
parameters but with an undef value.

I have gave an example below and shown that the third way of constructing the 
object doesn't work because the value undef is not an Int.

Which should be the recommended way to do this? The program wouldn't give errors if the 
attribute isa "maybe[Int]" but I feel that this isn't the right way to do that, 
and even in that case, the default value is still not set, so the program doesn't work 
correctly.

Is there a coercion required?

Thanks.

package TestMod;

use Moose;

has foo =>  (is =>  'ro', isa =>  'Int', default =>  123);

__PACKAGE__->meta->make_immutable;

package main;

use strict;

#This works; foo gets the default value:
my $t = TestMod->new;
print $t->foo;

#This also works; foo gets the provided value:
my $t = TestMod->new(foo =>  321);
print $t->foo;

#This doesn't work because foo is undefined:
my $t = TestMod->new(foo =>  undef);
print $t->foo;

Octavian


I'm quite new to this, so I don't know if this is the best or correct way to do it, but yes, you can use coercion to coerce from undef:

package TestMod;

use Moose;
use Moose::Util::TypeConstraints;

subtype 'TestMod::Int' => as 'Int';

coerce 'TestMod::Int'
    => from 'Undef'
        => via { 123; };

has foo     => (
    is      => 'ro',
    isa     => 'TestMod::Int',
    default => '123',
    coerce  => 1,
);

__PACKAGE__->meta->make_immutable;

package main;

use strict;
use warnings;

# Returns 123
my $t = TestMod->new();
print $t->foo . "\n";

# Returns 321
$t = TestMod->new(foo => 321);
print $t->foo . "\n";

# Returns 123
$t = TestMod->new(foo => undef);
print $t->foo . "\n";

1;

Reply via email to