ennuikiller
ennuikiller

Reputation: 46965

perl Moose accessor madness - can't define only a reader or writer accessor!

So I'm just trying to do a very simple thing: define a custom reader accessor for a moose attribute. So I try this:

has 'compiled_regex' => ( 
    isa => 'RegexpRef', 
    is => 'rw', 
    reader => 'get_compiled', 
);

but get_compiled never gets called, presumably because compiled_regex is read/write. Ok, no problem. I next try this:

 has 'compiled_regex' => ( 
     isa => 'RegexpRef', 
     writer => '_compile', 
     reader => 'get_compiled', 
 );

and that produces the following error:

Can't locate object method "compiled_regex" via package "PrettyRegex" at ../lib/Pretty/Regexs.pm line 39.

which refers to this line which is in the _compile method:

$self->compiled_regex(qr/$self->regex/);

Now I haven't gotten much sleep in the past 3 days so maybe I'm confused, but it seems that even if this did work, it would create an infinite regress since I've defined the writer as _compile ... so what am I missing here?

tried Sinan answer but still getting:

Can't locate object method "compiled_regex" via package "PrettyRegex" at ../lib/Pretty/Regexs.pm line 41.

Upvotes: 0

Views: 1797

Answers (3)

hobbs
hobbs

Reputation: 239980

Er? If your reader is called get_compiled, and your writer is called _compile, then you don't have a method named compiled_regex, and it should be obvious why a call to that nonexistent method would fail. You need to take several steps back and explain what you're trying to do, instead of what's going wrong with the way you've tried to do it.

Upvotes: 0

cjm
cjm

Reputation: 62109

I'm unclear on what you're trying to do. reader and writer are methods that Moose creates for you, not methods that you write and it calls.

I think you need to restate your question to explain the higher-level problem that you're trying to solve. I expect there's a better way to do it than you've currently thought of, but we can't be sure without knowing what you're really trying to do.

If you're trying to get your custom method called when the attribute is read, just name the reader something else (like _get_compiled_regex), and name your method compiled_regex. Or use a method modifier on the reader method. (That's probably better, because then you won't forget to die if somebody passes a parameter to your reader method, trying to set the attribute.)

You also might want to have a trigger on some other attribute that clears this one.

Upvotes: 2

Sinan Ünür
Sinan Ünür

Reputation: 118138

I keep guessing at what the actual question is, but I have a feeling the following corresponds to it:

package My::M;

use Moose;
use namespace::autoclean;

has 'compiled_regex' => (
    isa => 'RegexpRef',
    is  => 'ro',
    writer => '_set_compiled_regex',
);

sub compile {
    my $self = shift;
    my ($pat) = @_;
    $self->_set_compiled_regex(qr/$pat/);
    return;
}

__PACKAGE__->meta->make_immutable;

package main;
use strict; use warnings;

my $m = My::M->new;
$m->compile( '^\W+\z' );

if ( '@#$%%$' =~ $m->compiled_regex ) {
    print "Hmph!\n";
}

Upvotes: 0

Related Questions