in reply to Perl/Moose calling writer doesnt work

I concur with haukex that you should make a SSCCE to demonstrate/research your issue. Something very simple like:

# 1210614.pl package MyClass { use Moose; has FileName => (is => 'rw', isa => 'Str', writer => 'SetFileName' +); sub SetFileName { my $self = shift; my $arg = shift; warn "I am here with $arg"; } }; package main { my $obj = MyClass->new; $obj->SetFileName('/foo/bar'); };
This will show you the error clearly. Output:
$ perl 1210614.pl You are overwriting a locally defined method (SetFileName) with an acc +essor ...

As you can see this is not what specifying a custom writer does. As far as I understand it, specifying a custom writer property for an attribute simply changes the name of the writer from the default.

# 1210614-1.pl package MyClass { use Moose; has FileName => (is => 'rw', isa => 'Str', writer => 'SetFileName' +); }; package main { my $obj = MyClass->new; $obj->SetFileName('/foo/bar'); warn $obj->FileName; };
Output:
$ perl 1210614-1.pl /foo/bar at 1210614-1.pl line 9.

For what you are doing your code should use a custom type check, or a coercion, or a trigger instead.

# 1210614-2.pl package MyClass { use Moose; has FileName => (is => 'rw', isa => 'Str', trigger => \&SetFileNam +e); sub SetFileName { my $self = shift; my $arg = shift; warn "I am here with $arg"; } }; package main { my $obj = MyClass->new; $obj->SetFileName('/foo/bar'); };
Output:
$ perl 1210614-2.pl I am here with /foo/bar at 1210614-2.pl line 7.

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Perl/Moose calling writer doesnt work
by jorba (Sexton) on Mar 10, 2018 at 13:36 UTC

    That makes a lot of sense. If changing the writer only changes the name of the accessor, rather than allowing you to build your own custom version, that explains the error message and the failure to work. Off to investigate custom type chacks coercions and triggers. Only bad news is this means I need to rewrite a lot of my code, but then, perhaps it will work properly. Many thanx

      It looks like your current code can be used just by removing the writer parameter. It looks, to me, like you are making some checks in SetFileName and then set the parameter using the standard accessor. Thus, something like this should work for you:

      use 5.010; package MyClass { use Moose; has FileName => (is => 'rw', isa => 'Str'); sub SetFileName { my $self = shift; my $arg = shift; warn "I am here with $arg"; $self->FileName($arg) if $arg =~ /foo/; }; }; package main { my $obj = MyClass->new; $obj->SetFileName('/bar/baz'); say "FileName is: ", $obj->FileName; $obj->SetFileName('/foo/bar'); say "FileName is: ", $obj->FileName; };

      Though normally, if you want to force use of a custom writer you would change the default writer to start with an underscore to indicate that it should be treated as a private method (Note: treating underscore methods as private is a convention, it is not enforced):

      use 5.010; package MyClass { use Moose; has FileName => (is => 'rw', isa => 'Str', writer => "_SetFileName +"); sub SetFileName { my $self = shift; my $arg = shift; warn "I am here with $arg"; $self->_SetFileName($arg) if $arg =~ /foo/; }; }; package main { my $obj = MyClass->new; $obj->SetFileName('/bar/baz'); say "FileName is: ", $obj->FileName; $obj->SetFileName('/foo/bar'); say "FileName is: ", $obj->FileName; };

      Also note that your custom SetFileName will not be called if FileName is passed to new(). For that you would have to do something in BUILD or else some of the other special methods or such.

      Good Day,
          Dean