Sewi has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I blessed a hash on a module
my $self = bless {},$class
Other parts of the project may change the blessed hash, but I need to know if it was changed or not.
If there any chance of doing this without writing a tie-handler?
I thought of something like...
sub SET { my $self = shift; $self->{_changed} = 1; }

edit: Others are allowed to change the hash and I don't care about the keys they add. It's going to be a session hash and I want to refresh the disk store only if there are changes.

Replies are listed 'Best First'.
Re: Catching writes to a bless'ed hash
by JavaFan (Canon) on Aug 24, 2009 at 10:35 UTC
    If you don't want other code to alter attributes, then perhaps using a hashref isn't the right way to implement an object.

    Inside out objects are designed to prevent this. And with 5.10.x, implementing inside out objects is much easier:

    use strict; use warnings; use Hash::Util::FieldHash; fieldhash my %attr1; # You need one for each attribute. sub new {bless \do {my $var}, shift} sub set_attr1 { my $self = shift; $attr1{$self} = shift; } sub get_attr1 { my $self = shift; $attr1{$self} } etc.
    Since the attribute is tucked inside a lexical variable, it's impossible for code defined outside of the scope to touch the attribute.

    There's also a couple of modules out there to help you implement inside out objects, but I don't think they make use of fieldhashes (meaning they do extra work at DESTROY and CLONE time). Of course, if you're stuck with an old perl, those modules are the way to go.

Re: Catching writes to a bless'ed hash
by jethro (Monsignor) on Aug 24, 2009 at 10:20 UTC

    If you are sure that everyone uses your setter-methods to change the values in your object then your fine with something like this

    If not, you might store a hash-number of all keys and values into your object. If you don't need to check too often, this would cost less time than tie. Be careful with the hash function. For example if you need to differentiate between undef and empty string you should add a constant for defined values.

Re: Catching writes to a bless'ed hash
by ikegami (Patriarch) on Aug 24, 2009 at 13:51 UTC

    You want SET called when someone writes to the hash? That's what tie does. You want a tied hash without the hash being tied? That makes no sense. Explain yourself.

Re: Catching writes to a bless'ed hash
by Anonymous Monk on Aug 24, 2009 at 10:14 UTC