Kelp
view release on metacpan or search on metacpan
lib/Kelp/Base.pm view on Meta::CPAN
package Kelp::Base;
use strict;
use warnings;
use feature ();
use Carp;
require namespace::autoclean;
require Kelp::Util;
sub import
{
my $class = shift;
my $caller = caller;
# Do not import into inherited classes
return if $class ne __PACKAGE__;
my $base = shift || $class;
if ($base ne '-strict') {
no strict 'refs';
no warnings 'redefine';
if ($base ne '-attr') {
Kelp::Util::load_package($base);
push @{"${caller}::ISA"}, $base;
}
*{"${caller}::attr"} = sub { attr($caller, @_) };
namespace::autoclean->import(
-cleanee => $caller
);
}
strict->import;
warnings->import;
feature->import(':5.10');
}
sub new
{
my $self = shift;
return bless {@_}, $self;
}
sub attr
{
my ($class, $name, $default) = @_;
if (ref $default && ref $default ne 'CODE') {
croak "Default value for '$name' can not be a reference.";
}
# Readonly attributes are marked with '-'
my $readonly = $name =~ s/^\-//;
# Remember if default is a function
my $default_sub = ref $default eq 'CODE';
{
no strict 'refs';
no warnings 'redefine';
*{"${class}::$name"} = sub {
return $_[0]->{$name} = $_[1] if @_ > 1 && !$readonly;
return $_[0]->{$name} if exists $_[0]->{$name};
return $_[0]->{$name} = $default_sub ? $default->($_[0]) : $default;
};
}
}
1;
__END__
=pod
=head1 NAME
Kelp::Base - Simple lazy attributes
=head1 SYNOPSIS
use Kelp::Base;
attr source => 'dbi:mysql:users';
attr user => 'test';
attr pass => 'secret';
attr opts => sub { { PrintError => 1, RaiseError => 1 } };
attr dbh => sub {
my $self = shift;
DBI->connect( $self->sourse, $self->user, $self->pass, $self->opts );
};
( run in 1.356 second using v1.01-cache-2.11-cpan-99c4e6809bf )