The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Tie::Proxy::Changes - Track changes in your tied objects

SYNOPSIS

In any tied class:

 use Tie::Proxy::Changes;
 use Tie::Hash;
 
 our @ISA=qw/Tie::StdHash/;

 sub FETCH {
     my $self=shift;
     my $key=shift;
     if (exists $self->{$key}) {
         return Tie::Proxy::Changes->new($self,$key,$self->{$key});
     }
     else {
         return Tie::Proxy::Changes->new($self,$key);
     }
 }

DESCRIPTION

Sometimes a tied object needs to keep track of all changes happening to its data. This includes substructures with multi-level data. Returning a Tie::Proxy::Changes object instead of the raw data will result in a STORE call whenever the data is changed.

Here is a small example to illustrate to problem.

package main;
tie %data 'TiedObject';
$data{FOO}={}; #Calls STORE(FOO,{})
$data{FOO}->{Bar}=1; #calls just FETCH.

But when TiedObject is changed, it does this:

package TiedObject;
#...
sub FETCH {
    my $self=shift;
    my $key=shift;
    #... $data=something.
    # return $data # Not anymore.
    return Tie::Proxy::Changes->new($self,$key,$data);
}
package main;
tie %data 'TiedObject';
$data{FOO}={}; #Calls STORE(FOO,{})
$data{FOO}->{Bar}=1; #calls FETCH and then STORE(FOO,{Bar=>1}).

AUTOVIVIFICATION

This module can also (or exclusivly) be used to make autovivification work. Some tied datastructures convert all mulit-level data they get into tied objects.

When perl gets an undef from a FETCH call, it calls STORE with an empty reference to an array or a hash and then changes that hash. Some tied objects however can not keep this reference, because they save it in a different way.

The solution is to have FETCH return an empty Tie::Proxy::Changes object, and if the object is changed, STORE of the tied object will be called with the given key

my $self=shift;
my $key=shift;
...
#return undef; # Not anymore
return Tie::Proxy::Changes->new($self,$key);

If the object is just tested for existance of substructures, no STORE is called.

METHODS

new (OBJECT, KEY, [DATA])

Creates a new Tie::Proxy::Changes, on every change of its content OBJECT->STORE(KEY,MODIFIED DATA) is called.

INTERNAL METHODS

These are used to provide the right access for overload and tie. They shouldn't be called at any rate.

getarray

This gets called when Tie::Proxy::Changes plays arrayref by overload.

gethash

This gets called when Tie::Proxy::Changes plays hash by overload.

getbool

This gets called when Tie::Proxy::Changes is asked if it is true or false. Returns true if this has content and that is true.

SCALAR

Returns the size of the data.

See perltie (Somehow Pod::Coverage annoys me about this method).

BUGS

This won't work if you structure contains Refernces to SCALAR or other REFs, since overload is used, and there is no way to access the contained data if @{}, %{} and ${} is overloaded. If you find any way, drop me a mail.

SEE ALSO

perltie

LICENSE

Tie::Proxy::Changes is published under the terms of the MIT license, which basically means "Do with it whatever you want". For more information, see the LICENSE file that should be enclosed with this distribution. A copy of the license is (at the time of this writing) also available at http://www.opensource.org/licenses/mit-license.php.

AUTHOR

Marc "Maluku" Sebastian Lucksch

perl@marc-s.de