tags:

views:

101

answers:

3

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.
A: 

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";
}
Sinan Ünür
@Ether sorry, the comment referred to Sinan first answer, not to the one above.
ennuikiller
@Sinan please see my edited answer.
ennuikiller
+2  A: 

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.

cjm
here's the problem basically...I've defined a custom writer, say 'write_attr' on the attribute, say $self->my_attr. Now the last line of write_attr is $self->my_attr($some_var). This doesn't work for the reasons described in the question, but even if it did wouldn't it create an infinite regress since the last line of write_attr effectively calls write_attr?
ennuikiller
@ennui: "the last line of write_attr..." indicates the problem: this is not a sub that you should be defining yourself. It is automatically generated with the 'writer' directive.
Ether
ok, then how do I create a custom writer?
ennuikiller
Why do you think you need a custom writer? If the answer is along the lines of "because I want to run [some transformation] on the value passed in", you actually want a type constraint + coercion.
hdp
ok, thanks I'll give that a try
ennuikiller
+1  A: 

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.

hobbs
you see this is why perl oo with moose is, er, weird. compiled_regex should be an attribute, not a method.....how that attribute is set should be, er, irrelevant. –
ennuikiller