1 package Filter::Keyword;
3 # we need the PP implementation's version of remove_symbol
4 use Package::Stash::PP;
5 use Filter::Util::Call;
6 use B qw(svref_2object);
9 has target_package => (is => 'ro', required => 1);
11 has stash => (is => 'lazy');
15 Package::Stash::PP->new($self->target_package);
18 has keyword_name => (is => 'ro', required => 1);
20 has globref => (is => 'lazy', clearer => 'clear_globref');
23 no strict 'refs'; no warnings 'once';
24 \*{join'::',$_[0]->target_package,$_[0]->keyword_name}
27 after clear_globref => sub {
29 $self->stash->remove_symbol('&'.$self->keyword_name);
30 $self->globref_refcount(undef);
33 has globref_refcount => (is => 'rw');
37 warn "Save: ".$self->globref_refcount(svref_2object($self->globref)->REFCNT);
40 sub refcount_changed {
42 return 0 unless defined($self->globref_refcount);
43 svref_2object($self->globref)->REFCNT > $self->globref_refcount;
46 has info => (is => 'rw', predicate => 'has_info', clearer => 'clear_info');
54 my $name_re = '[A-Za-z][A-Za-z_0-9]*';
58 if ($self->has_info) {
59 if (delete $self->info->{first}) {
60 warn "Attempting short circuit";
64 my $info = $self->clear_info;
66 if ($self->refcount_changed) {
67 warn "Trapped: ".$info->{name};
68 my $name = $info->{name};
69 ${$info->{inner}} = sub { warn "Define ${name}" };
70 #$self->clear_globref;
71 s/{/; sub ${\$info->{name}} { my \$self = shift;/;
76 my $status = filter_read();
78 my $kw = $self->keyword_name;
79 if (/(.*?$kw\s+(${name_re}))(.*)\Z/s) {
80 my ($start, $name, $rest) = ($1, $2, $3);
81 $self->clear_globref if $self->refcount_changed;
82 no warnings 'redefine';
84 *{$self->globref} = sub (*;@) { $inner->(@_) };
88 name => $name, rest => $rest, first => 1,