File Coverage

blib/lib/Tie/Dir.pm
Criterion Covered Total %
statement 25 47 53.1
branch 1 14 7.1
condition 2 8 25.0
subroutine 8 15 53.3
pod 2 2 100.0
total 38 86 44.1


line stmt bran cond sub pod time code
1             #
2              
3             package Tie::Dir;
4              
5             =head1 NAME
6              
7             Tie::Dir - class definition for reading directories via a tied hash
8              
9             =head1 SYNOPSIS
10              
11             use Tie::Dir qw(DIR_UNLINK);
12            
13             # Both of these produce identical results
14             #(ie %hash is tied)
15             tie %hash, Tie::Dir, ".", DIR_UNLINK;
16             new Tie::Dir \%hash, ".", DIR_UNLINK;
17            
18             # This creates a reference to a hash, which is tied.
19             $hash = new Tie::Dir ".";
20            
21             # All these examples assume that %hash is tied (ie one of the
22             # first two tie methods was used
23            
24             # itterate through the directory
25             foreach $file ( keys %hash ) {
26             ...
27             }
28            
29             # Set the access and modification times (touch :-)
30             $hash{SomeFile} = time;
31            
32             # Obtain stat information of a file
33             @stat = @{$hash{SomeFile}};
34            
35             # Check if entry exists
36             if(exists $hash{SomeFile}) {
37             ...
38             }
39            
40             # Delete an entry, only if DIR_UNLINK specified
41             delete $hash{SomeFile};
42              
43             =head1 DESCRIPTION
44              
45             This module provides a method of reading directories using a hash.
46              
47             The keys of the hash are the directory entries and the values are a
48             reference to an array which holds the result of C being called
49             on the entry.
50              
51             The access and modification times of an entry can be changed by assigning
52             to an element of the hash. If a single number is assigned then the access
53             and modification times will both be set to the same value, alternatively
54             the access and modification times may be set separetly by passing a
55             reference to an array with 2 entries, the first being the access time
56             and the second being the modification time.
57              
58             =over
59              
60             =item new [hashref,] dirname [, options]
61              
62             This method ties the hash referenced by C to the directory C.
63             If C is omitted then C returns a reference to a hash which
64             hash been tied, otherwise it returns the result of C
65              
66             The possible options are:
67              
68             =over
69              
70             =item DIR_UNLINK
71              
72             Delete operations on the hash will cause C to be called on the
73             corresponding file
74              
75             =back
76              
77             =back
78              
79             =head1 AUTHOR
80              
81             Graham Barr , from a quick hack posted by
82             Kenneth Albanowski to the perl5-porters mailing list
83             based on a neat idea by Ilya Zakharevich.
84              
85             =cut
86              
87 1     1   1954 use Symbol;
  1         1169  
  1         82  
88 1     1   7 use Carp;
  1         2  
  1         83  
89 1     1   981 use Tie::Hash;
  1         1227  
  1         28  
90 1     1   9 use strict;
  1         2  
  1         66  
91 1     1   5 use vars qw(@ISA $VERSION @EXPORT_OK);
  1         2  
  1         820  
92             require Exporter;
93              
94             @ISA = qw(Tie::Hash Exporter);
95             $VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
96             @EXPORT_OK = qw(DIR_UNLINK);
97              
98 0     0 1 0 sub DIR_UNLINK { 1 }
99              
100             sub new {
101 1     1 1 43 my $pkg = shift;
102 1         3 my $h;
103              
104 1 50 33     12 if(@_ && ref($_[0])) {
105 1         3 $h = shift;
106 1         7 return tie %$h, $pkg, @_;
107             }
108              
109 0         0 $h = {};
110 0         0 tie %$h, $pkg, @_;
111 0         0 return $h;
112             }
113              
114             sub TIEHASH {
115 1     1   3 my($class,$dir,$unlink) = @_;
116 1   50     9 $unlink ||= 0;
117 1         7 bless [$dir,undef,$unlink], $class;
118             }
119              
120             sub FIRSTKEY {
121 0     0   0 my($this) = @_;
122 0 0       0 if($this->[1]) {
123 0 0 0     0 eval { rewinddir($this->[1]) } or
  0         0  
124             opendir($this->[1],$this->[0]) or
125             croak "Can't read ".$this->[0].": $!";
126             }
127             else {
128 0         0 $this->[1] = gensym();
129 0 0       0 opendir($this->[1],$this->[0]) or
130             croak "Can't read ".$this->[0].": $!";
131             }
132 0         0 readdir($this->[1]);
133             }
134              
135             sub NEXTKEY {
136 0     0   0 my($this,$last) = @_;
137 0         0 readdir($this->[1]);
138             }
139              
140             sub EXISTS {
141 1     1   12 my($this,$key) = @_;
142 1         32 -e $this->[0] . "/" . $key;
143             }
144              
145             sub DESTROY {
146 0     0     my($this) = @_;
147 0 0         closedir($this->[1])
148             if($this->[1]);
149             }
150              
151             sub FETCH {
152 0     0     my($this,$key) = @_;
153 0           [stat($this->[0] . "/" . $key)];
154             }
155              
156             sub STORE {
157 0     0     my($this,$key,$data) = @_;
158 0 0         my($atime,$mtime) = ref($data) ? @$data : ($data,$data);
159 0           utime($atime,$mtime, $this->[0] . "/" . $key);
160             }
161              
162             sub DELETE {
163 0     0     my($this,$key) = @_;
164             # Only unlink if unlink-ing is enabled
165 0 0         unlink($this->[0] . "/" . $key)
166             if($this->[2] & DIR_UNLINK);
167             }
168              
169             1;
170