———package
DBIx::VersionedSubs::Hash;
use
strict;
$VERSION
=
'0.09'
;
=head1 NAME
DBIx::VersionedSubs::Hash - store subroutines in a simple hash
=head1 SYNOPSIS
package My::App;
use strict;
use base 'DBIx::VersionedSubs::Hash';
__PACKAGE__->{code} = {
say_hello => sub {print "Hello World"},
};
package main;
use strict;
my $app = My::App->new({code => {},dsn => $dsn );
while (my $request = Some::Server->get_request) {
$app->update_code(); # update code from the DB
$app->handle_request->($request);
}
=head1 ABSTRACT
This module overrides some methods in L<DBIx::VersionedSubs>
and replaces the normal namespace based code storage
with simple storage in a hash.
This is useful if you want multiple code versions
in a mod_perl environment for example.
=cut
=head2 C<< Package->new({ %ARGS }) >>
Creates a new object and initializes it from the class
default values as inherited from L<DBIx::VersionedSubs>.
If you pass in a hashref to the C<code> key, all subroutines will
be stored in it. You can also use this feature to pass in a package
hash (like C< %My::App:: >), then this module will be almost identical
in usage to L<DBIx::VersionedSubs> itself. The difference
between the two is that subroutine names with characters outside of C<\w>
will not create subroutines in other namespaces with this module.
=cut
sub
new {
my
(
$package
,
$args
) =
@_
;
my
$code
=
delete
$args
->{ code } || {};
my
$self
=
bless
$args
,
$package
;
$self
->setup(
%$args
);
$self
->{ code } =
$code
;
$self
;
};
sub
create_sub {
my
(
$self
,
$name
,
$code
) =
@_
;
my
$package
=
ref
$self
;
my
$ref
=
$self
->eval_sub(
$package
,
$name
,
$code
);
if
(
$ref
) {
if
(
$name
eq
'BEGIN'
) {
$ref
->(
$self
);
return
undef
}
else
{
$self
->{code}->{
$name
} =
$ref
;
$self
->code_source->{
$name
} =
$code
;
}
};
$ref
};
sub
destroy_sub {
my
(
$self
,
$name
) =
@_
;
delete
$self
->{code}->{
$name
};
};
=head2 C<< $app->dispatch( FUNCTION, ARGS ) >>
This is a shorthand method for
return $self->{code}->{$function}->(@ARGS);
except with error checking
=cut
sub
dispatch {
my
$self
=
shift
;
my
$name
=
shift
;
my
$code
=
$self
->{code}->{
$name
} ||
sub
{croak
"Undefined subroutine '$name' called."
};
goto
&$code
;
};
# Install our accessors
for
(
qw(code_source code_live code_history code_version verbose dsn)
) {
my
$name
=
$_
;
no
strict
'refs'
;
*{__PACKAGE__ .
"::$name"
} =
sub
{
@_
> 1 ?
$_
[0]->{
$name
} =
$_
[1] :
$_
[0]->{
$name
}
};
};
1
__END__
=head1 AUTHOR
Max Maischein, E<lt>corion@cpan.orgE<gt>
=head1 LICENSE
This module is licensed under the same terms as Perl itself.
=cut