App-SimpleBackuper
view release on metacpan or search on metacpan
local/lib/perl5/Package/Stash/PP.pm view on Meta::CPAN
package Package::Stash::PP;
use strict;
use warnings;
# ABSTRACT: Pure perl implementation of the Package::Stash API
our $VERSION = '0.40';
use B;
use Carp qw(confess);
use Scalar::Util qw(blessed reftype weaken);
use Symbol;
# before 5.12, assigning to the ISA glob would make it lose its magical ->isa
# powers
use constant BROKEN_ISA_ASSIGNMENT => ($] < 5.012);
# before 5.10, stashes don't ever seem to drop to a refcount of zero, so
# weakening them isn't helpful
use constant BROKEN_WEAK_STASH => ($] < 5.010);
# before 5.10, the scalar slot was always treated as existing if the
# glob existed
use constant BROKEN_SCALAR_INITIALIZATION => ($] < 5.010);
# add_method on anon stashes triggers rt.perl #1804 otherwise
# fixed in perl commit v5.13.3-70-g0fe688f
use constant BROKEN_GLOB_ASSIGNMENT => ($] < 5.013004);
# pre-5.10, ->isa lookups were cached in the ::ISA::CACHE:: slot
use constant HAS_ISA_CACHE => ($] < 5.010);
#pod =head1 SYNOPSIS
#pod
#pod use Package::Stash;
#pod
#pod =head1 DESCRIPTION
#pod
#pod This is a backend for L<Package::Stash> implemented in pure perl, for those without a compiler or who would like to use this inline in scripts.
#pod
#pod =cut
sub new {
my $class = shift;
my ($package) = @_;
if (!defined($package) || (ref($package) && reftype($package) ne 'HASH')) {
confess "Package::Stash->new must be passed the name of the "
. "package to access";
}
elsif (ref($package) && reftype($package) eq 'HASH') {
confess "The PP implementation of Package::Stash does not support "
. "anonymous stashes before perl 5.14"
if BROKEN_GLOB_ASSIGNMENT;
return bless {
'namespace' => $package,
}, $class;
}
elsif ($package =~ /\A[0-9A-Z_a-z]+(?:::[0-9A-Z_a-z]+)*\z/) {
return bless {
'package' => $package,
}, $class;
}
else {
confess "$package is not a module name";
}
}
sub name {
confess "Can't call name as a class method"
unless blessed($_[0]);
confess "Can't get the name of an anonymous package"
unless defined($_[0]->{package});
return $_[0]->{package};
}
sub namespace {
confess "Can't call namespace as a class method"
unless blessed($_[0]);
if (BROKEN_WEAK_STASH) {
no strict 'refs';
return \%{$_[0]->name . '::'};
}
else {
return $_[0]->{namespace} if defined $_[0]->{namespace};
{
no strict 'refs';
$_[0]->{namespace} = \%{$_[0]->name . '::'};
}
weaken($_[0]->{namespace});
return $_[0]->{namespace};
}
}
{
my %SIGIL_MAP = (
'$' => 'SCALAR',
'@' => 'ARRAY',
'%' => 'HASH',
'&' => 'CODE',
'' => 'IO',
);
sub _deconstruct_variable_name {
my ($variable) = @_;
my @ret;
if (ref($variable) eq 'HASH') {
@ret = @{$variable}{qw[name sigil type]};
}
else {
(defined $variable && length $variable)
|| confess "You must pass a variable name";
my $sigil = substr($variable, 0, 1, '');
if (exists $SIGIL_MAP{$sigil}) {
@ret = ($variable, $sigil, $SIGIL_MAP{$sigil});
}
else {
@ret = ("${sigil}${variable}", '', $SIGIL_MAP{''});
}
}
# XXX in pure perl, this will access things in inner packages,
# in xs, this will segfault - probably look more into this at
# some point
($ret[0] !~ /::/)
|| confess "Variable names may not contain ::";
return @ret;
}
}
sub _valid_for_type {
my ($value, $type) = @_;
if ($type eq 'HASH' || $type eq 'ARRAY'
|| $type eq 'IO' || $type eq 'CODE') {
return reftype($value) eq $type;
}
else {
my $ref = reftype($value);
return !defined($ref) || $ref eq 'SCALAR' || $ref eq 'REF' || $ref eq 'LVALUE' || $ref eq 'REGEXP' || $ref eq 'VSTRING';
}
}
sub add_symbol {
my ($self, $variable, $initial_value, %opts) = @_;
( run in 0.832 second using v1.01-cache-2.11-cpan-5735350b133 )