initial sketch
[p5sagit/Sub-ScalarLike.git] / lib / Sub / ScalarLike.pm
1 package Sub::ScalarLike;
2
3 use strict;
4 use warnings FATAL => 'all';
5 use Variable::Magic qw(wizard cast dispell);
6
7 my $wiz = wizard
8   data => sub { +{ guard => 0, pkg => $_[1] } },
9   fetch => sub {
10     my ($var, $data, $name) = @_;
11
12     return if $data->{guard};
13     local $data->{guard} = 1;
14
15     my $pkg = $data->{pkg};
16
17     return if $pkg->can($name);
18
19     return if $name =~ /^__/; # __PACKAGE__ et. al.
20
21     my $fqn = join '::', $pkg, $name;
22
23     my $sub = sub () :lvalue { $pkg->_SCOPE->{$name} };
24
25     { no strict 'refs'; *$fqn = $sub }
26
27     return
28   };
29
30 sub setup_for {
31   my ($pkg) = @_;
32   {
33    no strict 'refs';
34    cast %{"${pkg}::"}, $wiz, $pkg;
35   }
36 }
37
38 sub teardown_for {
39   my ($pkg) = @_;
40   {
41    no strict 'refs';
42    dispell %{"${pkg}::"}, $wiz;
43   }
44 }
45
46 1;