Class-DbC
view release on metacpan or search on metacpan
lib/Class/DbC.pm view on Meta::CPAN
package Class::DbC;
our $VERSION = '0.000002';
$VERSION = eval $VERSION;
use strict;
use Class::Method::Modifiers qw(install_modifier);
use Carp;
use Module::Runtime qw(require_module);
use Params::Validate qw(:all);
use Storable qw( dclone );
my %Spec_for;
my %Contract_pkg_for;
my %Contract_validation_spec = (
type => HASHREF,
optional => 1,
);
sub import {
strict->import();
my $class = shift;
my %arg = validate(@_, {
interface => \%Contract_validation_spec,
invariant => \%Contract_validation_spec,
extends => { type => SCALAR, optional => 1 },
clone_with => { type => CODEREF, optional => 1 },
constructor_name => { type => SCALAR, default => 'new' },
});
my $caller_pkg = (caller)[0];
$Spec_for{ $caller_pkg } = \%arg;
_handle_extentions($caller_pkg, $arg{extends});
_add_governor($caller_pkg);
}
sub merge {
my ($h1, $h2) = @_;
foreach my $k (keys %{ $h2 }) {
if (exists $h1->{$k}) {
if ( ref $h1->{$k} eq 'HASH'
&& ref $h2->{$k} eq 'HASH'
) {
merge($h1->{$k}, $h2->{$k});
}
}
else {
$h1->{$k} = $h2->{$k};
}
}
}
sub _handle_extentions {
my ($pkg, $super) = @_;
return unless $super;
require_module($super);
merge($Spec_for{$pkg}, $Spec_for{$super});
}
sub _add_governor {
my ($pkg) = @_;
no strict 'refs';
*{"${pkg}::govern"} = \&_govern;
}
sub _govern {
my $class = shift;
my ($pkg, $opt) = validate_pos(@_,
{ type => SCALAR },
{ type => HASHREF, default => { all => 1 } },
);
_validate_govern_options(%$opt);
if ($opt->{all}
|| ($opt->{emulate} && scalar keys %$opt == 1 )) {
$opt->{$_} = 1 for qw/pre post invariant/;
}
( run in 0.681 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )