Compositeパターン

やはり再帰に苦手意識がある。以前schemeを少しかじってみたのが救いで、そこいらをやりこめば苦手意識も消えるだろうと思っている。

use strict;
use warnings;

{
    package Entry;
    use strict;
    use warnings;
    sub add {}
    sub printList {die;}
    sub toString {}
}

{
    package File;
    use strict;
    use warnings;
    our @ISA = qw/Entry/;
    sub new {
        my ($class, $name, $size) = @_;
        my $self = {
            name => $name,
            size => $size,
        };
        return bless $self, $class;
    }
    sub getName { $_[0]->{name}; }
    sub getSize { $_[0]->{size}; }
    sub printList {
        my ($self, $prefix) = @_;
        if(defined($prefix)){
            print $prefix."/".$self->{name},"\n";
        } else {
            print "/".$self->{name},"\n";
        }
    }
}

{
    package Directory;
    use strict;
    use warnings;
    sub new {
        my ($class, $name) = @_;
        my $self = {
            directory => [],
            name => $name,
        };
        return bless $self, $class;
    }
    sub getName { $_[0]->{name}; }
    sub getSize { return 'test'; }
    sub add {
        my ($self, $entry) = @_;
        push @{$self->{directory}}, $entry;
        return $self;
    }
    sub printList{
        use Data::Dumper;
        my ($self, $prefix) = @_;
        if(defined($prefix)){
            print "/".$prefix."/".$self->getName(),"\n";
            for my $foo (@{$self->{directory}}) {
                $foo->printList("/".$prefix."/".$self->{name});
            }
        } else {
            print "/".$self->{name},"\n";
            for my $foo (@{$self->{directory}}) {
                $foo->printList($self->{name});
            }
        }
    }
}
use Data::Dumper;

my $root = Directory->new('root');

my $bin = Directory->new('bin');
my $usr = Directory->new('usr');
$root->add($bin);
$root->add($usr);

my $vi = File->new('vi', 1000);
$bin->add($vi);

$root->printList();

print Dumper($root);

#$vi->printList();