sub new {
my $class = shift;
my ($namespace) = @_;
- return bless { package => $namespace }, $class;
+ return bless { 'package' => $namespace }, $class;
}
=head2 name
=cut
+sub _valid_for_type {
+ my $self = shift;
+ 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';
+ }
+}
+
sub add_package_symbol {
my ($self, $variable, $initial_value) = @_;
? @{$variable}{qw[name sigil type]}
: $self->_deconstruct_variable_name($variable);
+ if (@_ > 2) {
+ $self->_valid_for_type($initial_value, $type)
+ || confess "$initial_value is not of type $type";
+ }
+
my $pkg = $self->name;
no strict 'refs';
my $namespace = $self->namespace;
- # FIXME
if (!exists $namespace->{$name}) {
- my $initial = $type eq 'ARRAY' ? []
- : $type eq 'HASH' ? {}
- : \undef;
- $self->add_package_symbol($variable, $initial)
+ # assigning to the result of this function like
+ # @{$stash->get_package_symbol('@ISA')} = @new_ISA
+ # makes the result not visible until the variable is explicitly
+ # accessed... in the case of @ISA, this might never happen
+ # for instance, assigning like that and then calling $obj->isa
+ # will fail. see t/005-isa.t
+ if ($type eq 'ARRAY' && $name ne 'ISA') {
+ $self->add_package_symbol($variable, []);
+ }
+ elsif ($type eq 'HASH') {
+ $self->add_package_symbol($variable, {});
+ }
+ else {
+ # FIXME
+ $self->add_package_symbol($variable)
+ }
}
my $entry_ref = \$namespace->{$name};
$io = $self->get_package_symbol($io_desc) if $self->has_package_symbol($io_desc);
}
elsif ($type eq 'ARRAY') {
- $scalar = $self->get_package_symbol($scalar_desc) if $self->has_package_symbol($scalar_desc);
+ $scalar = $self->get_package_symbol($scalar_desc);
$hash = $self->get_package_symbol($hash_desc) if $self->has_package_symbol($hash_desc);
$code = $self->get_package_symbol($code_desc) if $self->has_package_symbol($code_desc);
$io = $self->get_package_symbol($io_desc) if $self->has_package_symbol($io_desc);
}
elsif ($type eq 'HASH') {
- $scalar = $self->get_package_symbol($scalar_desc) if $self->has_package_symbol($scalar_desc);
+ $scalar = $self->get_package_symbol($scalar_desc);
$array = $self->get_package_symbol($array_desc) if $self->has_package_symbol($array_desc);
$code = $self->get_package_symbol($code_desc) if $self->has_package_symbol($code_desc);
$io = $self->get_package_symbol($io_desc) if $self->has_package_symbol($io_desc);
}
elsif ($type eq 'CODE') {
- $scalar = $self->get_package_symbol($scalar_desc) if $self->has_package_symbol($scalar_desc);
+ $scalar = $self->get_package_symbol($scalar_desc);
$array = $self->get_package_symbol($array_desc) if $self->has_package_symbol($array_desc);
$hash = $self->get_package_symbol($hash_desc) if $self->has_package_symbol($hash_desc);
$io = $self->get_package_symbol($io_desc) if $self->has_package_symbol($io_desc);
}
elsif ($type eq 'IO') {
- $scalar = $self->get_package_symbol($scalar_desc) if $self->has_package_symbol($scalar_desc);
+ $scalar = $self->get_package_symbol($scalar_desc);
$array = $self->get_package_symbol($array_desc) if $self->has_package_symbol($array_desc);
$hash = $self->get_package_symbol($hash_desc) if $self->has_package_symbol($hash_desc);
$code = $self->get_package_symbol($code_desc) if $self->has_package_symbol($code_desc);
$self->remove_package_glob($name);
- $self->add_package_symbol($scalar_desc => $scalar) if defined $scalar;
+ $self->add_package_symbol($scalar_desc => $scalar);
$self->add_package_symbol($array_desc => $array) if defined $array;
$self->add_package_symbol($hash_desc => $hash) if defined $hash;
$self->add_package_symbol($code_desc => $code) if defined $code;