Phew, ok, I think I really got it down good now. I did some more refinement of how things work, too. Here's what I got:
package File::Collector::DateAnalyzer ;
use strict; use warnings;
use Log::Log4perl::Shortcuts qw(:all);
use File::Collector::DateAnalyzer::Iterator;
use parent qw ( File::Collector );
sub add_resources {
my $s = shift;
$s->SUPER::add_resources(@_);
$s->{files}{some_files} = File::Collector::DateAnalyzer::Ite
+rator->new();
$s->{files}{other_files} = File::Collector::DateAnalyzer::Ite
+rator->new();
$s->_test_blah;
}
sub _test_blah {
my $s = shift;
foreach my $file ($s->get_files) {
$s->{files}{some_files}->add_file($s->{files}{all}{$file});
}
}
return 1;
package File::Collector::DateAnalyzer::Iterator ;
use strict;
use warnings;
use parent qw (File::Collector::Iterator);
use Log::Log4perl::Shortcuts qw(:all);
sub print_blah_names {
my $s = shift;
print $s->next->{short_path} . "\n\n";
}
1;
package File::Collector::Iterator ;
use strict;
use warnings;
use Carp;
use Log::Log4perl::Shortcuts qw(:all);
sub new {
my $class = shift;
bless [@_], $class;
}
sub next {
my $s = shift;
my $last = shift @$s;
push @$s, $last;
return $last;
}
sub add_file {
my $s = shift;
pop @$s;
push @$s, shift;
push @$s, '';
}
sub print_short_names {
my $s = shift;
print $s->next->{short_path} . "\n";
}
sub selected_file {
my $s = shift;
$s->[0];
}
sub do {
my $self = shift;
bless \$self, 'File::Collector::Iterator::All';
}
sub DESTROY {
my $s = shift;
$s->next while ($s->selected_file);
}
{
package File::Collector::Iterator::All;
use Log::Log4perl::Shortcuts qw(:all);
sub AUTOLOAD {
our $AUTOLOAD;
my $self = shift;
my @method = split /::/, $AUTOLOAD;
my $method = pop @method;
$$self->$method(@_) while ($$self->selected_file);
$$self->next(@_);
}
}
A few notes:
Iterator is now a circular queue, terminated with an empty string.
Attributes of File::Collector subclasses are now iterators themselves. This let me get rid of the AUTOLOAD in File::Collector.
I restrucutred File::Collector->{files} as you suggested.
This simple test works:
{
my $da;
# 1
lives_ok { $da = File::Collector::DateAnalyzer->new('t/test_data/many
+_files'); }
'creates DateAnalyzer object';
$da->{files}{some_files}->do->print_blah_names;
$da->{files}{some_files}->do->print_short_names;
}
I will improve upon the do method calls so I don't have the ugly hashes in there and will use a simple AUTOLOAD so I can do $da->some_files->do->print_blah_names
How does it look to you?
|