Moose, how to change the attribute value only when it is equal to $ undef?

Now:

has 'id' => (
    is => 'rw',
    isa => 'Str',
    default => sub { "id" . int(rand(1000))+1 }
);

Works fine,

PKG->new(id => 'some'); #the id is "some"
PKG->new()              #the id is #id<random_number>

In the following scenario:

my $value = undef;
PKG->new(id => $value);

(of course) got an error:

Attribute (id) does not pass the type constraint because: Validation failed for 'Str' with value undef at /Users/me/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/darwin-thread-multi-2level/Moose/Exception.pm line 37

The question arises:

How to achieve a value change after it is set to undef (and only when it is equal to $ undef)? In this way,

has 'id' => (
    is => 'rw',
    isa => 'Str|Undef',  #added undef to acceptable Type
    default => sub { "id" . int(rand(1000))+1 }
);

Now he accepts $undef, but I do not want $undef, but I want "id" . int(rand(1000))+1. How to change attribute value after ?

aftercalled only for accessories, not for designers. Maybe some weird coercionfrom Undefto Str- but just for that one attribute?

Ps: use is PKG->new( id => $value // int(rand(10000)) )not an acceptable solution. The module must accept $undefand must silently change it to a random number.

+4
3

:: Tiny , . :

use strict;
use warnings;

{
    package Local::Test;
    use Moose;
    use Types::Standard qw( Str Undef );

    my $_id_default = sub { "id" . int(rand(1000)+1) };

    has id => (
        is      => 'rw',
        isa     => Str->plus_coercions(Undef, $_id_default),
        default => $_id_default,
        coerce  => 1,
    );

    __PACKAGE__->meta->make_immutable;
}

print Local::Test->new(id => 'xyz123')->dump;
print Local::Test->new(id => undef)->dump;
print Local::Test->new->dump;

MooseX:: UndefTolerant, undef, , . undef ; .

+6

, Moose "BUILD", .

#!/usr/bin/perl

package Test;
use Moose;

has 'id' => (
    is => 'rw',
    isa => 'Str|Undef',
);

sub BUILD {
    my $self = shift;
    unless($self->id){
        $self->id("id" . (int(rand(1000))+1));
    }
}
1;

package Main;


my $test = Test->new(id => undef);
print $test->id; ###Prints random number if id=> undef

BUILD : http://metacpan.org/pod/Moose::Manual::Construction#BUILD

+2

@choroba , triggers. , . id=>undef, .

use Modern::Perl;

package My;
use namespace::sweep;
use Moose;

my $_id_default = sub { "id" . int(rand(100_000_000_000)+1) };
my $_check_id = sub { $_[0]->id(&$_id_default) unless $_[1] };

has id => (
    is      => 'rw',
    isa => 'Str|Undef',
    default => $_id_default,
    trigger => $_check_id,
);

__PACKAGE__->meta->make_immutable;

package main;

say My->new->id;
say My->new(id=>'aaa')->id;
say My->new(id=>undef)->id;
0

Source: https://habr.com/ru/post/1532214/


All Articles