#!/usr/bin/perl use strict; use warnings; ######################################################################## package mytest; sub new { bless({obj=>{}, update=>0 },$_[0]); } sub add { my $self=shift; my $name=shift; my $obj=$self->{obj}; if($name && !exists($obj->{$name})) { my $val=shift; $obj->{$name}=mytest::child->new($name,$val,sub{ $self->{update}=1 }); $self->{update}=1; } } sub get { my $obj=shift->{obj}; return exists($obj->{$_[0]})?$obj->{$_[0]}:undef; } sub save { my $self=shift; my $obj=$self->{obj}; if(%$obj && $self->{update}) { # save dummy print $_->serialized() for(values(%$obj)); $self->{update}=0; } } sub DESTROY { my $self=shift; $self->save(); for(values(%{$self->{obj}})) { delete($_->{do_update}); } } ######################################################################## package mytest::child; sub new { my $class=shift; bless({ name => shift, val => shift, do_update => shift, },$class); } sub val { my $self=shift; if(@_) { $self->{val}=shift; $self->{do_update}->() if($self->{do_update}); } $self->{val}; } sub name{ shift()->{name}; } sub serialized { '{ '.join(', ',map{"$_ => ".$_[0]->{$_}}qw(name val))." }\n"; } ######################################################################## ######################################################################## ######################################################################## package main; use Data::Dumper; my $t=mytest->new(); $t->add(qw(test1 A)); $t->add(qw(test2 B)); $t->add(qw(test3 C)); $t->add(qw(test4 D)); print Dumper($t);