1 package Filter::Keyword;
4 use Filter::Keyword::Filter;
5 use Scalar::Util qw(weaken);
6 use Package::Stash::PP;
7 use B qw(svref_2object);
9 sub _compiling_file () {
11 while (my @caller = caller(++$depth)) {
12 if ($caller[3] =~ /::BEGIN$/) {
13 # older perls report the BEGIN in the wrong file
14 return $depth > 1 ? (caller($depth-1))[1] : $caller[1];
24 my $file = _compiling_file;
26 my $filter = $filters{$file} ||= Filter::Keyword::Filter->new;
28 my $parser = $filter->parser;
29 $parser->add_keyword($self);
30 $self->keyword_parser($parser);
35 my $stash = $self->stash;
36 if (my $shadowed = $stash->get_symbol('&'.$self->keyword_name)) {
37 $stash->remove_symbol('&'.$self->keyword_name);
38 $stash->add_symbol('&__'.$self->keyword_name, $shadowed);
44 $self->keyword_parser->remove_keyword($self);
45 $self->clear_keyword_parser;
49 has keyword_parser => (is => 'rw', weak_ref => 1, clearer => 1);
51 has target_package => (is => 'ro', required => 1);
52 has keyword_name => (is => 'ro', required => 1);
53 has parser => (is => 'ro', required => 1);
55 has stash => (is => 'lazy');
59 Package::Stash::PP->new($self->target_package);
62 has globref => (is => 'lazy', clearer => 'clear_globref');
65 no strict 'refs'; no warnings 'once';
66 \*{join'::',$_[0]->target_package,$_[0]->keyword_name}
69 after clear_globref => sub {
71 $self->stash->remove_symbol('&'.$self->keyword_name);
72 $self->globref_refcount(undef);
75 has globref_refcount => (is => 'rw');
79 $self->globref_refcount(svref_2object($self->globref)->REFCNT);
84 return 0 unless defined($self->globref_refcount);
85 svref_2object($self->globref)->REFCNT > $self->globref_refcount;