Entering MooseX, Part the Seventh

Well in my last post I created a very small API of a two keys

  1. requires and
  2. 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.

8d68f0f1f765ad06063c799250bfac7a.jpg


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations