This file is indexed.

/usr/share/perl5/Alzabo/ChangeTracker.pm is in libalzabo-perl 0.92-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
123
124
125
126
127
128
package Alzabo::ChangeTracker;

use strict;

use vars qw( $VERSION $STACK @CHANGES );

$VERSION = 2.0;

use Params::Validate qw( :all );
Params::Validate::validation_options( on_fail => sub { Alzabo::Exception::Params->throw( error => join '', @_ ) } );

1;

sub new
{
    my $proto = shift;
    my $class = ref $proto || $proto;

    ++$STACK;

    my $self = $STACK;
    bless \$self, $class;
}

sub add
{
    my $self = shift;

    validate_pos( @_, { type => CODEREF } );

    push @CHANGES, shift;
}

sub backout
{
    my $self = shift;

    $_->() foreach @CHANGES;

    @CHANGES = ();
}

sub DESTROY
{
    --$STACK;

    @CHANGES = () unless $STACK;
}

__END__

=head1 NAME

Alzabo::ChangeTracker - Saves a set of changes as callbacks that can be backed out if needed

=head1 SYNOPSIS

  use Alzabo::ChangeTracker;

  my $x = 0;
  my $y = 1;
  sub foo
  {
     my $tracker = Alzabo::ChangeTracker->new;
     $tracker->add( sub { $x = 0; } );

     $x = 1;

     bar();

     eval { something; };

     $tracker->backout if $@;
  }

  sub bar
  {
     my $tracker = Alzabo::ChangeTracker->new;
     $tracker->add( sub { $y = 1; } );

     $y = 2;
  }


=head1 DESCRIPTION

The trick ...

We only want to have one object of this type at any one time.  In
addition, only the stack frame that created it should be able to clear
it (except through a backout).  Why?  Here's an example in pseudo-code
to help explain it:

 sub foo
 {
   create a tracker;
   store some change info in the tracker;

   call sub bar;

   store some change info in the tracker;

   # point Y

   clear changes in tracker;
 }

 sub bar
 {
   create a tracker; # internally, we really just increment our stack count

   store some change info in the tracker;

   clear changes in tracker; # point X
 }

If at point X we were to really clear out the changes, even the
changes just from sub bar, we'd have a problem.  Because if at point
Y, things go to hell and we want to back out the changes, we want to
back out the changes from sub foo _AND_ sub bar.  However, if bar is
also an entry point we want to be able to track changes in bar and
clear them from bar.

=head1 AUTHOR

Dave Rolsky, <autarch@urth.org>

=cut