Blob


1 #!/usr/bin/perl
3 # Modify the iterative version of data_for_path to handle both depth-first or
4 # breadth-first traversal. Use an optional third argument to allow the user
5 # to decide which to use:
7 #my $depth = data_for_path( $start_dir, $threshold, 'depth-first');
8 #my $breadth = data_for_path( $start_dir, $threshold, 'breadth-first');
10 use v5.24;
11 use warnings;
12 use strict;
13 use utf8;
14 use File::Basename;
15 use File::Spec::Functions;
17 sub data_for_path {
18 my ($path, $threshold, $order) = @_;
19 my $data = {};
20 my @queue = ( [$path, 0, $data] );
21 while (my $next = shift @queue) {
22 my ($path, $level, $ref) = @$next;
23 my $basename = basename($path);
24 $ref->{$basename} = do {
25 if (-f $path or -l $path) { undef }
26 else {
27 my $hash = {};
28 if ($level < $threshold) {
29 opendir(my $dh, $path);
30 my @new_paths = map {
31 catfile($path, $_);
32 } grep { ! /^\.\.?\z/ } readdir $dh;
33 if ($order eq 'breadth-first') {
34 unshift @queue, map { [$_, $level+1, $hash] } @new_paths;
35 } elsif ($order eq 'depth-first') {
36 push @queue, map { [$_, $level+1, $hash] } @new_paths;
37 }
38 }
39 $hash;
40 }
41 };
42 }
43 $data;
44 }
46 sub dump_data_for_path {
47 my ($path, $data, $level) = @_;
48 if (not defined $data) {
49 print "$path\n";
50 return;
51 }
52 foreach (sort keys %$data) {
53 dump_data_for_path("$path/$_", $data->{$_});
54 }
55 }
56 my $start_dir = '/home/jrmu/documents';
57 my $threshold = 3;
58 my $depth = data_for_path( $start_dir, $threshold, 'depth-first');
59 my $breadth = data_for_path( $start_dir, $threshold, 'breadth-first');