Aion
view release on metacpan or search on metacpan
lib/Aion/Meta/FeatureConstruct.pm view on Meta::CPAN
package Aion::Meta::FeatureConstruct;
use common::sense;
use Aion::Meta::Util qw//;
Aion::Meta::Util::create_getters(qw/
pkg name
write read
getvar ret
/);
Aion::Meta::Util::create_accessors(qw/
init_arg
set get has clear weaken
accessor_name reader_name writer_name predicate_name clearer_name
initer not_specified
getter setter selfret
/);
# ÐонÑÑÑÑкÑоÑ
sub new {
my ($cls, $pkg, $name) = @_;
bless {
pkg => $pkg,
name => $name,
initializer => <<'END',
if (exists $value{%(init_arg)s}) {
%(initer)s
}%(not_specified)s
END
destroyer => <<'END',
if (%(has)s) {
eval {
%(cleaner)s
};
warn $@ if $@;
}
END
accessor => <<'END',
package %(pkg)s {
sub %(accessor_name)s%(attr)s {
if (@_>1) {
my ($self, $val) = @_;
%(setter)s
%(selfret)s
} else {
my ($self) = @_;
%(getter)s
}
}
}
END
reader => <<'END',
package %(pkg)s {
sub %(reader_name)s {
my ($self) = @_;
%(read)s
}
}
END
writer => <<'END',
package %(pkg)s {
sub %(writer_name)s {
my ($self, $val) = @_;
%(write)s
%(selfret)s
}
}
END
predicate => <<'END',
package %(pkg)s {
sub %(predicate_name)s {
my ($self) = @_;
%(has)s
}
}
END
clearer => <<'END',
package %(pkg)s {
sub %(clearer_name)s {
my ($self) = @_;
if (%(has)s) {
%(cleaner)s%(clear)s
}
%(clearret)s
}
}
END
accessor_name => '%(name)s',
reader_name => '_get_%(name)s',
writer_name => '_set_%(name)s',
attr => '',
write => '%(preset)s%(set)s%(trigger)s',
read => '%(access)s%(getvar)s%(release)s%(ret)s',
setter => '%(write)s',
getter => '%(read)s',
initer => "%(initvar)s%(write)s",
init_arg => '%(name)s',
initvar => 'my $val = delete $value{%(init_arg)s};',
not_specified => '',
preset => '',
set => '$self->{%(name)s} = $val;',
trigger => '',
selfret => '$self',
access => '',
getvar => '%(get)s',
get => '$self->{%(name)s}',
release => '',
ret => '',
predicate_name => 'has_%(name)s',
has => 'exists $self->{%(name)s}',
clearer_name => 'clear_%(name)s',
clear => 'delete $self->{%(name)s}',
clearret => '$self',
cleaner => '',
weaken => 'Scalar::Util::weaken(%(get)s);',
}, ref $cls || $cls;
}
sub add_attr { shift->_expand('attr', @_) }
sub add_preset { shift->_expand('preset', @_) }
sub add_trigger { shift->_expand('trigger', @_) }
sub add_cleaner { shift->_expand('cleaner', @_) }
sub add_access { shift->_expand('access', @_) }
sub add_release {
my $self = shift;
@$self{qw/getvar ret/} = ('my $val = %(get)s;', '$val') if $self->{ret} eq '';
$self->_expand('release', @_)
}
sub _expand(@) {
my ($self, $key, $code, $shift) = @_;
if(ref $self->{$key}) {
if($shift) { unshift @{$self->{$key}}, $code }
else { push @{$self->{$key}}, $code }
}
elsif ($self->{$key} eq '') {
$self->{$key} = $code;
}
else {
$self->{$key} = $shift? [$code, $self->{$key}]: [$self->{$key}, $code];
}
$self
}
for my $key (qw/initializer destroyer accessor writer reader predicate clearer/) {
*$key = sub {
my ($self) = @_;
_idents($self->_resolv($self->{$key}))
}
}
sub _resolv {
my ($self, $s) = @_;
$s = join '', @$s if ref $s;
$s =~ s{%\((\w*)\)s}{
die "has: not construct `$1`\!" unless exists $self->{$1};
$self->_resolv($self->{$1})
}ge;
$s
}
sub _idents {
local ($_) = @_;
my $indent;
s{(^\t*)|;[\t ]*(\S)}{
if(defined $1) { $indent = $1 } else { ";\n$indent$2" }
}gme;
$_
}
1;
__END__
lib/Aion/Meta/FeatureConstruct.pm view on Meta::CPAN
=head2 name
Attribute name. Getter.
$::construct->name # -> "my_feature"
=head2 write
Code for writing the value. Getter.
$::construct->write # \> %(preset)s%(set)s%(trigger)s
=head2 read
Code to read the value. Getter.
$::construct->read # \> %(access)s%(getvar)s%(release)s%(ret)s
=head2 getvar
Variable to receive the value. Getter.
$::construct->getvar # \> %(get)s
=head2 ret
Value return code. Getter.
$::construct->ret # -> ''
=head2 init_arg
The key is in the initialization hash. Accessor.
$::construct->init_arg # \> %(name)s
=head2 set
Code for setting the value to the object hash. Accessor.
$::construct->set # \> $self->{%(name)s} = $val;
=head2 get
Code for getting a value from an object hash. Accessor.
$::construct->get # \> $self->{%(name)s}
=head2 has
Code for checking the existence of a value. Accessor.
$::construct->has # \> exists $self->{%(name)s}
=head2 clear
Code for deleting a value. Accessor.
$::construct->clear # \> delete $self->{%(name)s}
=head2 weaken
Link weakening code. Accessor.
$::construct->weaken # \> Scalar::Util::weaken(%(get)s);
=head2 accessor_name
The name of the accessor method. Accessor.
$::construct->accessor_name # \> %(name)s
=head2 reader_name
Reader method name. Accessor.
$::construct->reader_name # \> _get_%(name)s
=head2 writer_name
Writer method name. Accessor.
$::construct->writer_name # \> _set_%(name)s
=head2 predicate_name
Predicate method name. Accessor.
$::construct->predicate_name # \> has_%(name)s
=head2 clearer_name
The name of the cleanser method. Accessor.
$::construct->clearer_name # \> clear_%(name)s
=head2 initer
Attribute initialization code. Accessor.
$::construct->initer # \> %(initvar)s%(write)s
=head2 not_specified
Initialization code if no value is specified. Accessor.
$::construct->not_specified # -> ''
=head2 getter
Getter code in the accessor. Accessor.
$::construct->getter # \> %(read)s
=head2 setter
Setter code in the accessor. Default: '%(write)s'.
$::construct->setter # \> %(write)s
=head2 selfret
Return code from setter. Accessor.
$::construct->selfret # \> $self
( run in 1.009 second using v1.01-cache-2.11-cpan-5a3173703d6 )