package File::Cache::Parsed; use strict; use warnings; use List::Util qw(first); use List::MoreUtils qw(firstidx); use Path::Class; sub new { my ($class)=@_; return bless { parsers=>[], cache=>{}, }=>$class; } sub add_parser { my ($self,$rx,$parser)=@_; my $old_parser=first {$_->[0] eq $rx} @{$self->{parsers}}; if ($old_parser) { $old_parser->[1]=$parser; } else { push @{$self->{parsers}},[$rx,$parser]; } return; } sub del_parser { my ($self,$rx)=@_; my $i=firstidx {$_->[0] eq $rx} @{$self->{parsers}}; return if $i<0; splice @{$self->{parsers}},$i,1; $self->invalidate($rx); return; } sub get { my ($self,$filename)=@_; return $self->{cache}{$filename} if exists $self->{cache}{$filename}; my $contents=file($filename)->slurp; my $pp=first {$filename =~ m{$_->[0]}} @{$self->{parsers}}; if ($pp) { return $self->{cache}{$filename}=$pp->[1]->($filename,$contents); } else { return $self->{cache}{$filename}=$contents; } } sub invalidate { my ($self,$rx)=@_; my $count=0; for my $filename (keys %{$self->{cache}}) { if ($filename =~ m{$rx}) { delete $self->{cache}{$filename}; ++$count; } } return $count; } 1;