On Mon, Mar 28, 2011 at 8:28 AM, Peter Gordon <[email protected]> wrote:
> I have a small class, where I would like the variables to be read only
> by external calls, but rw for internal access.
>
> Why?
> If there is a variable defined as lazy and ro, writing the value fails.
> So it needs to be rw. Is there a recommended way of dealing with this
> problem?

I'm not sure what this means. If the value is lazy and ro then it has
to be set via a builder or default, or supplied via construction. I
see from the code below that you're trying to manually set the value
of the attribute inside the builder, and that's I think the confusion
you have.

The *return* value from the builder is used to populate the attribute.

package Class;
use Moose;
has foo => ( is => 'lazy', is => 'ro', builder => '_build_foo');
sub _build_foo { return 123 }

package main;
use 5.12.3; # import say

say Class->new->foo; # prints 123

> The other reason I have is that the class in question is instantiated
> with a filename, and the filename must exist. If the file gets deleted
> before the default for value is performed, I would like to get an error.
> The easiest way that I found for that was to read and write the filename
> value, forcing the isa FileExists. Is there a better way of doing this?

Yes. Use the FileExists type constraint directly in the builder.

sub value_builder {
find_type_constraint('FileExists')->assert_valid($my->fileName);
return $value }

> subtype 'FileExists'
>    => as 'Str'
>    => where { -e $_ };
>
> has 'fileName' => (is => 'rw',
>                   required => 1,
>                   isa => 'FileExists',
>                  ) ;
>
> has 'value'   => (is => 'rw',
>               lazy => 1,
>               builder => 'value_builder',
>              ) ;
>
> sub value_builder {
>    my $my = shift ;
>
>    $my->fileName($my->fileName) ; # This forces the isa requirement
>    $my->value('123') ;
> }
>



-Chris

Reply via email to