use Attribute::Handlers;
use Carp;
sub private :ATTR(CODE) {
my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
my $name = *{$symbol}{NAME};
*{$symbol} = sub {
croak "Function $name is declared private in $package"
if caller ne $package;
$referent->(@_)
}
}
####
package EventHandlers;
our %EventHandlers;
use Attribute::Handlers;
use Carp;
sub Event :ATTR(CODE) {
my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
my $name = *{$symbol}{NAME};
$EventHandlers{$name} = 1;
}
####
package Annotations;
my %Annotations;
sub Annotate {
my ($sub, %annotations) = @_;
bless $sub, Annotations;
my $h = $Annotations{$sub} ||= {};
@$h{keys %annotations} = values %annotations;
}
sub annotation {
my ($this, $name) = @_;
$Annotations{$this}{$name}
}
####
package Events;
use Annotations;
use Attribute::Handlers;
sub Event :ATTR(CODE) {
my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
Annotations::Annotate($referent, eventhandler => 1);
}
####
if (my $event = MyEvents->can($CGI->param('event'))) {
die unless $event->annotation('eventhandler');
MyEvents->$event();
}
####
$event->{eventhandler}
####
annotation($event, 'eventhandler')