Aion
view release on metacpan or search on metacpan
lib/Aion/Meta/Util.pm view on Meta::CPAN
sub create_getters(@) {
my $pkg = caller;
eval "package $pkg; sub $_ {
die \"$_ is ro\" if \@_ > 1;
shift->{$_}
} 1" or die for @_;
}
# СоздаÑÑ Ð³ÐµÑÑеÑÑ/ÑеÑÑеÑÑ
sub create_accessors(@) {
my $pkg = caller;
eval "package $pkg; sub $_ {
if(\@_ > 1) { \$_[0]->{$_} = \$_[1]; \$_[0] }
else { shift->{$_} }
} 1" or die for @_;
}
# ÐÑовеÑÑеÑ, Ð¸Ð¼ÐµÐµÑ Ð»Ð¸ подпÑогÑамма Ñело
sub subref_is_reachable {
my ($subref) = @_;
require B;
my $cv = B::svref_2object($subref);
return !(B::class($cv->ROOT) eq 'NULL' && !${ $cv->const_sv });
}
# СимволÑное пÑедÑÑавление знаÑениÑ
use constant {
MAX_DEPTH => 2,
MAX_HASH_SIZE => 6,
MAX_ARRAY_SIZE => 6,
MAX_SCALAR_LENGTH => 255,
};
sub val_to_str($;$);
sub val_to_str($;$) {
my ($v, $depth) = @_;
if (!defined $v) { 'undef' }
elsif (ref $v eq 'ARRAY') {
if($depth > MAX_DEPTH) { '[...]' }
else {
$depth++;
join '', '[', join(', ', map({ val_to_str($_, $depth) } (
@$v > MAX_ARRAY_SIZE ? @$v[0..MAX_ARRAY_SIZE] : @$v
)), @$v > MAX_ARRAY_SIZE ? '...' : ()), ']';
}
}
elsif (ref $v eq 'HASH') {
if($depth > MAX_DEPTH) { '{...}' }
else {
$depth++;
join '', '{', join(', ', map({
qq{$_ => ${\val_to_str($v->{$_}, $depth)}} } (
keys %$v > MAX_HASH_SIZE
? (sort keys %$v)[0..MAX_HASH_SIZE]
: sort keys %$v
)), keys %$v > MAX_HASH_SIZE ? '...' : ()), '}';
}
}
else {
my $no_str = ref $v || Scalar::Util::looks_like_number($v);
if(ref $v eq 'Regexp') {
$v = "$v";
$v =~ s{^\(\?\^?([a-z]*):(.*)\)$}{qr/$2/$1}si;
}
else {
$v = overload::Overloaded($v) && !overload::Method($v, '""')
? join("#", Scalar::Util::reftype($v), Scalar::Util::refaddr($v))
: "$v";
}
$v = substr($v, 0, MAX_SCALAR_LENGTH) . '...'
if length($v) > MAX_SCALAR_LENGTH;
$no_str ? $v : "'${\ $v =~ s/['\\]/\\$&/gr }'"
}
}
1;
__END__
=encoding utf-8
=head1 NAME
Aion::Meta::Util - helper functions for creating meta data
=head1 SYNOPSIS
package My::Meta::Class {
use Aion::Meta::Util;
create_accessors qw/age/;
create_getters qw/name/;
}
my $class = bless {name => 'car'}, 'My::Meta::Class';
$class->age(20);
$class->age # => 20
$class->name # => car
eval { $class->name('auto') }; $@ # ~> name is ro
=head1 DESCRIPTION
Meta-classes that support the creation of features and function signatures (i.e., the internal kitchen of Aion) require their own small implementation, which this module provides.
=head1 SUBROUTINES
=head2 create_getters (@getter_names)
Creates getters.
=head2 create_accessors (@accessor_names)
Creates getter-setters.
=head2 subref_is_reachable ($subref)
Checks whether the subroutine has a body.
( run in 1.620 second using v1.01-cache-2.11-cpan-39bf76dae61 )