Subject: | Using Moose's before to alter method arguments clashes with Privacy |
Date: | Mon, 24 Jul 2017 20:14:48 +0000 |
To: | "bug-MooseX-Privacy [...] rt.cpan.org" <bug-MooseX-Privacy [...] rt.cpan.org> |
From: | Bram Vanroy <bramvanroy [...] hotmail.com> |
[Topic described in more detail on StackOverflow: https://stackoverflow.com/q/45286468/1150683]
When setting a variable as Private (but Protected will also be affected), it seems impossible to change it from inside Moose's before/after/around subs because you then get a 'Attribute X is private' error - even if you are doing this in the same class. A helpful user on SO found that `Class::MOP::Method::Wrapped` is the caller for before/after/around subs, and that is why MooseX::Private throws the error - it's no the Class itself.
This should not happen IMHO. To fit inside the Moose system, it is paramount that MooseX modules take into consideration the possibilities of the standalone Moose module. Before/after/around are often used, and part of Moose's core so it would be nice to see that Privacy works with it in full as well.
Full code to test:
# Banana.pm
package Banana;
use strict;
use warnings;
use Carp qw( confess );
use Moose;
use MooseX::Privacy;
has ['peel', 'edible'] => (
is => 'ro',
isa => 'Bool',
required => 1,
);
has 'color' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'grow_params' => (
is => 'rw',
isa => 'HashRef',
traits => [qw/Private/],
);
sub grow {
my ($self, $params) = @_;
$self->grow_params($params);
}
before 'grow_params' => sub {
my ($self, $params) = @_;
# Setting default value
$params->{'overripe'} = exists $params->{'overripe'} ? $params->{'overripe'} : 0;
# Making sure its boolean
confess "Argument 'overripe' has to be 0 or 1"
unless ($params->{'overripe'} == 0 || $params->{'overripe'} == 1);
};
1;
# run.pl
use strict;
use warnings;
use File::Basename qw(fileparse dirname);
use Cwd qw(abs_path);
# Add current directory to @INC
use lib (fileparse(abs_path($0)))[1];
use Banana;
my $chiquita = Banana->new({
peel => 1,
edible => 0,
color => 'green'
});
$chiquita->grow({
size => 'medium',
color => 'yellow'
});