1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
use strict;
use warnings;
use Test::More;
use Test::Exception;
use Class::MOP;
{
package My::Package::Stash;
use strict;
use warnings;
use base 'Package::Stash';
use metaclass;
use Symbol 'gensym';
__PACKAGE__->meta->add_attribute(
'namespace' => (
reader => 'namespace',
default => sub { {} }
)
);
sub new {
my $class = shift;
$class->meta->new_object(__INSTANCE__ => $class->SUPER::new(@_));
}
sub add_package_symbol {
my ($self, $variable, $initial_value) = @_;
my ($name, $sigil, $type) = $self->_deconstruct_variable_name($variable);
my $glob = gensym();
*{$glob} = $initial_value if defined $initial_value;
$self->namespace->{$name} = *{$glob};
}
}
{
package My::Meta::Package;
use strict;
use warnings;
use base 'Class::MOP::Package';
sub _package_stash {
$_[0]->{_package_stash} ||= My::Package::Stash->new($_[0]->name);
}
}
# No actually package Foo exists :)
my $meta = My::Meta::Package->initialize('Foo');
isa_ok($meta, 'My::Meta::Package');
isa_ok($meta, 'Class::MOP::Package');
ok(!defined($Foo::{foo}), '... the %foo slot has not been created yet');
ok(!$meta->has_package_symbol('%foo'), '... the meta agrees');
lives_ok {
$meta->add_package_symbol('%foo' => { one => 1 });
} '... the %foo symbol is created succcessfully';
ok(!defined($Foo::{foo}), '... the %foo slot has not been created in the actual Foo package');
ok($meta->has_package_symbol('%foo'), '... the meta agrees');
my $foo = $meta->get_package_symbol('%foo');
is_deeply({ one => 1 }, $foo, '... got the right package variable back');
$foo->{two} = 2;
is($foo, $meta->get_package_symbol('%foo'), '... our %foo is the same as the metas');
ok(!defined($Foo::{bar}), '... the @bar slot has not been created yet');
lives_ok {
$meta->add_package_symbol('@bar' => [ 1, 2, 3 ]);
} '... created @Foo::bar successfully';
ok(!defined($Foo::{bar}), '... the @bar slot has still not been created');
ok(!defined($Foo::{baz}), '... the %baz slot has not been created yet');
lives_ok {
$meta->add_package_symbol('%baz');
} '... created %Foo::baz successfully';
ok(!defined($Foo::{baz}), '... the %baz slot has still not been created');
done_testing;
|