Commit | Line | Data |
d8316caf |
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; |