Ambrosia
view release on metacpan or search on metacpan
lib/Ambrosia/Utils/Container.pm view on Meta::CPAN
sub size
{
scalar keys %{$_[0]->__data};
}
sub list
{
return keys %{$_[0]->__data};
}
sub clone
{
my $self = shift;
if ( @_ )
{#deep clone
return $self->clone(1);
}
else
{
my $obj = $self->new;
$obj->__data = { map { $_ => $self->__data->{$_} } keys %{$self->__data} };
return $obj;
}
}
sub as_hash
{
my $self = shift;
if ( @_ )
{
return $self->SUPER::as_hash(1)->{__data};
}
return { map { $_ => $self->__data->{$_} } keys %{$self->__data} };
}
sub info
{
my $self = shift;
return join "\n", map { my $d = $self->__data->{$_}; $_ . '=' . ( ref $d || $d ) } keys %{$self->__data};
}
sub info_dump
{
my $self = shift;
return join "\n", map { my $d = $self->__data->{$_}; $_ . '=' . ( ref $d ? Dumper($d) : $d ) } keys %{$self->__data};
}
1;
package deferred;
use Ambrosia::error::Exceptions;
use overload
'%{}' => \&as_hash,
'@{}' => \&__as_array,
'${}' => \&__as_scalar,
'&{}' => \&__as_func,
'*{}' => \&__as_glob,
'==' => \&__as_bool,
'bool'=> \&__as_bool,
'""' => \&__as_string,
'0+' => \&__as_number,
'fallback' => 1
;
sub call(&)
{
return bless {code => $_[0]}, 'deferred';
}
sub as_hash
{
return $_[0] if caller eq __PACKAGE__;
local $@;
unless ( exists $_[0]->{value} )
{
my $h = $_[0]->{code}->();
if ( ref $h eq 'HASH' )
{
$_[0]->{value} = $h;
}
elsif( ref $h && eval{$h->can('as_hash')})
{
$_[0]->{value} = $h->as_hash();
}
}
elsif ( eval{$_[0]->{value}->can('as_hash')} )
{
$_[0]->{value} = $_[0]->{value}->as_hash();
}
return $_[0]->{value};
}
sub __as_any
{
unless ( exists $_[0]->{value} )
{
$_[0]->{value} = $_[0]->{code}->();
}
return $_[0]->{value};
}
sub __as_array
{
goto &__as_any;
}
sub __as_scalar
{
goto &__as_any;
#unless ( exists $_[0]->{scalar} )
#{
# $_[0]->{scalar} = '' . $_[0]->{code}->();
#}
#return $_[0]->{scalar};
}
sub __as_func
{
goto &__as_any;
}
sub __as_glob
{
goto &__as_any;
}
sub __as_bool
{
goto &__as_any;
#unless ( exists $_[0]->{bool} )
#{
# $_[0]->{bool} = '' . $_[0]->{code}->();
#}
#return $_[0]->{bool};
}
sub __as_string
{
#warn join ' ', grep $_, caller(0);
#warn join ' ', grep $_, caller(1);
#warn join ' ', grep $_, caller(2);
#warn join ' ', grep $_, caller(3);
#warn join ' ', grep $_, caller(4);
#warn join ' ', grep $_, caller(5);
goto &__as_any;
#unless ( exists $_[0]->{string} )
#{
# $_[0]->{string} = '' . $_[0]->{code}->();
#}
#return $_[0]->{string};
}
sub __as_number
{
goto &__as_any;
}
sub ref
{
my $self = shift;
return CORE::ref $self->__as_any();
}
sub AUTOLOAD
{
my $self = shift;
my @param = @_;
my $type = CORE::ref($self) or return;
my ($func) = our $AUTOLOAD =~ /(\w+)$/
or throw Ambrosia::error::Exception 'Error: cannot resolve AUTOLOAD: ' . $AUTOLOAD;
warn "AUTOLOAD: $func\n";
my $p = $self->__as_any;
if( CORE::ref($p) && eval {$p->can($func)} )
{
return $p->$func(@param );
}
else
{
throw Ambrosia::error::Exception 'Error: cannot resolve: ' . $AUTOLOAD;
( run in 0.814 second using v1.01-cache-2.11-cpan-df04353d9ac )