Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl Moose如何仅在属性值为$undef时更改属性值?_Perl_Moose - Fatal编程技术网

Perl Moose如何仅在属性值为$undef时更改属性值?

Perl Moose如何仅在属性值为$undef时更改属性值?,perl,moose,Perl,Moose,现在有: has 'id' => ( is => 'rw', isa => 'Str', default => sub { "id" . int(rand(1000))+1 } ); 工作正常,以下各项: PKG->new(id => 'some'); #the id is "some" PKG->new() #the id is #id<random_number> (当然)出现了一个错

现在有:

has 'id' => (
    is => 'rw',
    isa => 'Str',
    default => sub { "id" . int(rand(1000))+1 }
);
工作正常,以下各项:

PKG->new(id => 'some'); #the id is "some"
PKG->new()              #the id is #id<random_number>
(当然)出现了一个错误:

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
问题是:

如何在设置为undef(且仅当值为$undef)后更改该值?所以

现在,它接受
$undef
,但我不想要
$undef
,而是想要
的“id”。整数(兰特(1000))+1
。设置属性值后如何更改属性值

之后的
仅为访问器调用,而不是为构造函数调用。可能是从
unde
Str
的一些奇怪的
强制
——但只针对这一个属性

注:使用
PKG->new(id=>$value//int(rand(10000))
不是一个可接受的解决方案。该模块应接受
$unde
,并应以静默方式将其更改为随机数。

的目标之一是使向单个属性添加强制变得非常容易。下面是一个例子:

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;

您还可以查看传递给构造函数的
undef
值的作用,就像它们被完全忽略一样。但这不包括将unde传递给访问器;只有构造函数。

这里有一种替代方法,使用Moose的构建方法,在创建对象后调用该方法

#!/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
有关构建的更多信息,请单击此处:
@choroba在一篇评论中提到了。基于此,找到了下一个解决方案。在
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;

在使用setter之后,是否也要将unde更改为随机值?你是在寻找一个触发器吗?检查moose中的构建方法,但是
$obj->id(unde)
?一个
微小的
模块有很多文档:)-但是对于很多事情来说,它似乎是一个很棒的模块。。。需要RTFM,但为此,它可以工作。:)谢谢,很好!没有任何外部模块。Thanx!:)
#!/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
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;