Entering MooseX, Part the Seventh
Well in my last post I created a very small API of a two keys
- requires and
- one_of
Now I have to get down and dirty and write up some code to handle this API. Now the logic will be in the same place namely 'MooseX::Meta::Method::Role::Authorized' and in a rewritten 'authorized_do' sub.
Well I start out the same with
sub authorized_do {
my $self = shift;
my $method = shift;
my $code = shift;
my ($instance) = @_;
my $requires = $method->requires;
...
Well to start that little validation I added allows me to be very sure that in this sub my $requires will have well formatted and workable data so no need to check it again I can just play with it.
Now it is late and of course I decided to get a little creative and I came up with next it this
foreach my $key (keys($requires)){
my $author_sub = '_authorize_'.$key;
$self->$author_sub($requires->{$key},$instance);
}
$code->(@_);
So I am doing that old Perl trick of assembling my sub I want to call from instance data and then attempting to to call it against $self'
So I added in another two subs like this
sub _authorize_requires {
my $self = shift;
my ($roles,$instance) = @_;
foreach my $role (@{$roles}){
die "You Die Now GI!!"
if (!Moose::Util::does_role($instance,$role));
}
return 1;
}
sub _authorize_one_of {
my $self = shift;
my ($roles,$instance) = @_;
foreach my $role (@{$roles}){
return 1
if (Moose::Util::does_role($instance,$role));
}
die "You Die Now GI!!";
}
I then reran my little test again and it ran just dandy.
Now in programming it in this way I have accomplished two things.
First I have made the API part of my code somewhat easier to expand as all I need to do is add in a correctly named sub and logic, adjust my validation to allow the new key and things should just work.
Secondly I have just opened my code up to more potential bugs as now a user can send down a key that is not part of the API and I will throw an error as my code will try and execute it and fail. Fortunately the way I did things here I am not open to an a nasty injection attack as I have the '_authorize_' tacked onto the beginning of my sub name so it cannot run a sub without such a name.
So what are my options as there are a few but at this time I will just go with the quick and dirty 'can' so I end up with
foreach my $key (keys($requires)){
my $author_sub = '_authorize_'.$key;
next
unless ($self->can($author_sub));
$self->$author_sub($requires->{$key},$instance);
}
$code->(@_);
So with that little adding I tighten up my API so I think I need to get a little R&R now.
Leave a comment