File: RefCountedFile.pm

package info (click to toggle)
libvcp-perl 0.9-20050110-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,608 kB
  • ctags: 827
  • sloc: perl: 18,194; makefile: 42; sh: 11
file content (122 lines) | stat: -rw-r--r-- 2,200 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package VCP::RefCountedFile;

=head1 NAME

VCP::RefCountedFile - An object that deletes a named file when nothing refers to it any more.

=head1 SYNOPSIS

   use VCP::RefCountedFile;

   {
      my $fn = VCP::RefCountedFile->new( "/path/to/name" );
      print $fn;
   }  ## "name" is deleted here.

=head1 DESCRIPTION

An object that mimics a string, but which refers to a file and deletes the
file when the last reference to the file via such objects disappears.

=cut

$VERSION = 1;

use strict ;

use Carp ;
use overload (
   '""' => \&as_string,
   'cmp' => sub {
      "$_[0]" cmp "$_[1]"
   },
);

use VCP::Debug ':debug' ;
use VCP::Logger qw( pr );
use VCP::Utils 'empty' ;

sub new {
   my $class = ref $_[0] ? ref shift : shift;
   my $self = bless \my( $value ), $class;
   $self->set( @_ ) if @_;
   return $self;
}


sub as_string {
   my $self = shift;
   return $$self;
}


my %ref_counts;
    ## Each file gets a ref count.  This hash maintains that ref_count.


sub set {
   my $self = shift;

   my ( $value ) = @_;

   if ( !empty( $$self ) ) {
      my $fn = "$$self";  ## for simplicity
      if (
         $ref_counts{$fn}
         && --$ref_counts{$fn} < 1
         && -e $fn
      ) {
         if ( debugging ) {
            my @details ;
            my $i = 2 ;
            do { @details = caller($i++) } until $details[0] ne __PACKAGE__ ;
            debug "$self unlinking '$fn' in " . join( '|', @details[0,1,2,3]) ;
         }

         unlink $fn or pr "$! unlinking $fn\n"
      }
   }

   $$self = $value;

   ++$ref_counts{$$self} unless empty $$self;
}


END {
   if ( debugging && ! $ENV{VCPNODELETE} ) {
      for ( sort keys %ref_counts ) {
	 if ( -e $_ ) {
	    pr "$_ not deleted" ;
	 }
      }
   }
}


sub DESTROY {
   return if $ENV{VCPNODELETE};
   my $self = shift ;
   $self->set( undef );
}


=head1 SUBCLASSING

This class is a bless scalar.

=head1 COPYRIGHT

Copyright 2000, Perforce Software, Inc.  All Rights Reserved.

This module and the VCP package are licensed according to the terms given in
the file LICENSE accompanying this distribution, a copy of which is included in
L<vcp>.

=head1 AUTHOR

Barrie Slaymaker <barries@slaysys.com>

=cut

1