Ticket #1 (closed task: fixed)
Whatbot Command refactor for Attribute support
| Reported by: | oz | Owned by: | oz |
|---|---|---|---|
| Priority: | major | Milestone: | whatbot 0.95 |
| Component: | Command | Version: | |
| Keywords: | Cc: |
Description (last modified by oz) (diff)
Implement Perl Attributes in whatbot Commands.
Edited due to oZ being a moron.
We're effectively changing the command architecture so that by default, a module can be called with its name as the class entry, and then each subroutine can be a sub command, which can be overridden by attributes, similar to Catalyst.
Attributes:
- Command?
- Sets the subcommand as the subroutine name. ( > module subroutine )
- CommandRegEx?
- Sets the subcommand as a custom name using regex. ( > module [x] )
- GlobalRegEx?
- Sets the subcommand as a global name using regex. ( > [x] )
- Monitor?
- Forces all messages to pass through this routine. ( > * )
Each method that implements the attribute gets $self and $message. RegEx? methods also get $captures, an arrayref of captures.
Let's say we have a hypothetical URL command, in Command/URL.pm, called whatbot::Command::URL. Just basics, here.
########################################################################### # whatbot/Command/URL.pm ########################################################################### # the whatbot project - http://www.whatbot.org ########################################################################### package whatbot::Command::URL; use Moose; BEGIN { extends 'whatbot::Command'; } sub register { my ($self) = @_; $self->command_priority('Extension'); $self->require_direct(0); } 1;
By creating the module, we already have a command called "URL" or "url", which would show up in help, command lists, etc. Saying 'url' in a channel or chat window would enter the class, but not do anything. So, we'll need a few methods. Let's first listen for anything that looks like a URL, whether it's directly spoken to your new class or not.
sub url_listen : GlobalRegEx('(https|http|ftp|news|feed|telnet)://([^\w]+)') { my ( $self, $message, $captures ) = @_; my $url = join( '://', $captures ); push( @{ $self->{'_urls'} }, { 'user' => $message->from, 'url' => $url } ); }
This module would probably want a more stateless storage mechanism, but let's do this for the lols. Now we need a way to gather some information from the module. You probably want some querying functions, a few ways to get all URLs from a domain, or a user, or whatever. We're not going to go into that here, but let's at least find a way to get the last URL mentioned in the chat, but you have to specifically ask for it.
sub last : Command { my ( $self, $message ) = @_; if ( defined $self->{'_urls'} ) { my $url_hash = $self->{'_urls'}->[scalar(@{ $self->{'_urls'} }) - 1]; return $url_hash->{'username'} . ' contributed ' . $url_hash->{'url'}; } return 'I got nothin.'; }
The last subroutine would respond to 'url last', and return the username and URL if one has been noticed, and a failure message if nothing has been said since the module's been listening.
This is going to be an epic pain to get started, but is ultimately going to make whatbot development easier.
