File Coverage

blib/lib/File/Find/Random.pm
Criterion Covered Total %
statement 41 41 100.0
branch 12 12 100.0
condition 2 2 100.0
subroutine 10 10 100.0
pod 3 5 60.0
total 68 70 97.1


line stmt bran cond sub pod time code
1              
2             package File::Find::Random;
3 4     4   168034 use File::Find qw();
  4         10  
  4         109  
4 4     4   22 use strict;
  4         7  
  4         136  
5 4     4   5882 use File::Spec::Functions;
  4         7761  
  4         2505  
6 4     4   4698 use Error;
  4         51597  
  4         29  
7 4     4   578 use warnings;
  4         13  
  4         2025  
8             our $VERSION = '0.5';
9             package Error::File::Find::Random;
10             our @ISA = qw(Error);
11             $VERSION = 1;
12             package File::Find::Random;
13              
14             =head1 NAME
15              
16             File::Find::Random -
17              
18             =head1 SYNOPSIS
19              
20             use File::Find::Random;
21              
22            
23             my $file = File::Find::Random->find();
24              
25             my $file = File::Find::Random->find('path/');
26              
27             my $finder = File::Find::Random->new();
28             $finder->base_path('/foo/bar');
29             my $file = $finder->find();
30              
31             =head1 DESCRIPTION
32              
33             Randomly selects a file from a filesystem.
34              
35             =head1 METHODS
36              
37             =head2 new
38              
39             Returns a find object.
40              
41             =head2 base_path
42              
43             Sets or returns the base_path
44              
45             =head2 find
46              
47             The biggest function, can be called as a class method or a object method.
48             Automagically will set base_path if passed a parameter. Returns a random file.
49              
50             If it cannot find a file it will throw an exception of type Error::File::Find::Random.
51              
52             =cut
53              
54              
55             my $file;
56             my $error;
57             sub new {
58 16     16 1 4193 my $scalar = undef;
59 16         203 return bless \$scalar, shift;
60             }
61              
62             sub find {
63 17     17 1 71671 my $self = shift;
64 17 100       293 $self = $self->new() unless(ref($self));
65 17 100       73 if(@_) {
66 13         53 $self->base_path(shift());
67             }
68 17         99 $file = undef;
69 17         32 $error = undef;
70 17   100     167 File::Find::find(
71             {
72             wanted => \&find_wanted_cb,
73             preprocess => \&find_filter_cb,
74             no_chdir => 1,
75             },
76             $self->base_path || curdir()
77             );
78 17         67 my $found_file = $file;
79 17         28 $file = undef;
80 17 100       327 if(-d $found_file) {
81 1         46 die with Error::File::Find::Random -text => "Cannot find a file in this pass at '$error'\n";
82             }
83 16         194 return $found_file;
84             }
85              
86             sub find_filter_cb {
87 65 100   65 0 479 my @dirs = grep { $_ ne curdir() && $_ ne updir() } @_;
  770         15246  
88 65 100       788 if(@dirs) {
89 64         3184 return $dirs[rand(@dirs)]
90             }
91 1         6 $error = $File::Find::dir;
92 1         204 return;
93             }
94              
95             sub find_wanted_cb {
96 81     81 0 5661 $file = $_;
97             }
98              
99             sub base_path {
100 33     33 1 833 my $self = shift;
101 33 100       137 if(@_) {
102 16         51 $$self = shift;
103 16         53 return $self;
104             }
105 17         2591 return $$self;
106             }
107              
108             =head1 BUGS
109              
110             If the finder finds a empty directory or a finds itself in a place where it has no permissions to descend further, it will throw an error. This might be seen as a bug and might get fixed.
111              
112             While it is random which file is selected, there is no mechanism in place to counter the imbalance that occurs if you have varying depth of directories. However our use is on very big filesystem with equally distributed directory structures.
113              
114             =head1 AUTHOR
115              
116             Arthur Bergman
117             arthur@fotango.com
118             http://opensource.fotango.com/
119              
120             =head1 COPYRIGHT
121              
122             Copyright 2003 Fotango Ltd All Rights Reserved.
123              
124             This module is released under the same license as Perl itself.
125              
126             =cut
127              
128              
129             1; #this line is important and will help the module return a true value
130             __END__