1 package Filter::Keyword;
3 use Package::Stash::PP;
4 use Filter::Util::Call;
5 use B qw(svref_2object);
8 has target_package => (is => 'ro', required => 1);
10 has stash => (is => 'lazy');
14 Package::Stash::PP->new($self->target_package);
17 has keyword_name => (is => 'ro', required => 1);
19 has globref => (is => 'lazy', clearer => 'clear_globref');
22 no strict 'refs'; no warnings 'once';
23 \*{join'::',$_[0]->target_package,$_[0]->keyword_name}
26 after clear_globref => sub {
28 $self->stash->remove_symbol('&'.$self->keyword_name);
29 $self->globref_refcount(undef);
32 has globref_refcount => (is => 'rw');
36 warn "Save: ".$self->globref_refcount(svref_2object($self->globref)->REFCNT);
39 sub refcount_changed {
41 return 0 unless defined($self->globref_refcount);
42 svref_2object($self->globref)->REFCNT > $self->globref_refcount;
45 has info => (is => 'rw', predicate => 'has_info', clearer => 'clear_info');
53 my $name_re = '[A-Za-z][A-Za-z_0-9]*';
57 if ($self->has_info) {
58 if (delete $self->info->{first}) {
59 warn "Attempting short circuit";
63 my $info = $self->clear_info;
65 if ($self->refcount_changed) {
66 warn "Trapped: ".$info->{name};
67 my $name = $info->{name};
68 ${$info->{inner}} = sub { warn "Define ${name}" };
69 #$self->clear_globref;
70 s/{/; sub ${\$info->{name}} { my \$self = shift;/;
75 my $status = filter_read();
77 my $kw = $self->keyword_name;
78 if (/(.*?$kw\s+(${name_re}))(.*)\Z/s) {
79 my ($start, $name, $rest) = ($1, $2, $3);
80 $self->clear_globref if $self->refcount_changed;
81 no warnings 'redefine';
83 *{$self->globref} = sub (*;@) { $inner->(@_) };
87 name => $name, rest => $rest, first => 1,