examples/shell/tree.pl
#!/usr/bin/perl
use strict;
use warnings;

my $dir = '.';
if (@ARGV) {
    $dir = $ARGV[0];
}
traverse_dir('', $dir, 0);

sub traverse_dir {
    my ($dir, $thing, $depth) = @_;
    my $path = ($dir ? "$dir/$thing" : $thing);
    print " " x ($depth*3), "$thing\n";
    return if not -d $path;

    if (opendir my $dh, $path) {
        while (my $entry = readdir $dh) {
            next if $entry eq "." or $entry eq "..";
            traverse_dir ($path, $entry, $depth+1);
        }
    } else {
        print " " x ($depth*3-3), "#### Could not open $dir\n";
    }
    return;
}

examples/shell/tree_ff.pl
#!/usr/bin/perl
use strict;
use warnings;

use File::Find;

if (not @ARGV) {
    @ARGV = (".");
}

find (\&find_name, @ARGV);

sub find_name {
    # $File::Find::name looks like: 
    # dir/subdir/subdir/file.ext
    # split at / and at \  for both unix and windows
    my @directories = split m{[/\\]}, $File::Find::name;

    print "  " x (@directories -1); # () needed for precedence
    print "$_\n";
    return;
}

examples/shell/tree_file_find_rule.pl
#!/usr/bin/perl
use strict;
use warnings;

use File::Find::Rule;
my $dir = '.';
if (@ARGV) {
    $dir = shift;
}

foreach my $thing (File::Find::Rule->in($dir)) {
    my @parts = split m{/}, $thing;
    print "  " x @parts;
    print "$parts[-1]\n";
}