Skip Menu |

This queue is for tickets about the Moo CPAN distribution.

Report information
The Basics
Id: 78725
Status: rejected
Priority: 0/
Queue: Moo

People
Owner: Nobody in particular
Requestors: djerius [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.000001
Fixed in: (no value)



Subject: predicate doesn't trigger builder when is => 'lazy'
If an attribute is lazy its builder isn't triggered when its predicate is invoked: package Foo; use Moo; has 'lazy' => ( is => 'lazy', predicate => 1,); has 'builder' => ( is => 'ro', predicate => 1, builder => 1,); sub _build_lazy { return 1 }; sub _build_builder { return 1 }; my $x = Foo->new; print "builder: ", $x->has_builder || 0, "\n"; print "lazy: ", $x->has_lazy || 0, "\n"; results in builder: 1 lazy: 0 It may seem odd to have a predicate with a builder, but the two cases should be consistent. I think that as builders ensure that an attribute has a value, the predicate should always return true if a builder (lazy or not) is present. Whether it should trigger a lazy builder is another question. Thanks, Diab
Subject: Re: [rt.cpan.org #78725] predicate doesn't trigger builder when is => 'lazy'
Date: Fri, 3 Aug 2012 16:41:59 -0700
To: Diab Jerius via RT <bug-Moo [...] rt.cpan.org>
From: Karen Etheridge <ether [...] cpan.org>
On Wed, Aug 01, 2012 at 06:11:00PM -0400, Diab Jerius via RT wrote: Show quoted text
> If an attribute is lazy its builder isn't triggered when its predicate > is invoked...
Show quoted text
> It may seem odd to have a predicate with a builder, but the two cases > should be consistent. I think that as builders ensure that an attribute > has a value, the predicate should always return true if a builder (lazy > or not) is present. Whether it should trigger a lazy builder is another > question.
That's by design. Calling a predicate determines if an attribute *has* a value, not *if it could have a value* should its reader be called. If you really want to trigger an attribute to be built, call its reader method, which will either return the already-built value, or call the builder. (If you always want the builder to be called, then call the clearer first.)