#!/usr/bin/perl -w use strict; package HistoryObj; sub new { my $class = shift; my $self = { color => 'blue', texture => 'rusty metal', taste => 'salt', }; bless($self, $class); return $self; } #### { my %history; sub _log { my $self = shift; my $attrib = shift; my $value = $self->{$attrib}; push @{ $history{$self} }, [ $attrib, $value ]; } sub undo { my $self = shift; return unless (scalar @{ $history{$self} }); my ($attrib, $value) = @{ pop @{ $history{$self} } }; $self->{$attrib} = $value; } } #### sub color { my $self = shift; if (@_) { $self->_log('color'); $self->{color} = $_[0]; } return $self->{color}; } sub texture { my $self = shift; if (@_) { $self->_log('texture'); $self->{texture} = $_[0]; } return $self->{texture}; } sub taste { my $self = shift; if (@_) { $self->_log('taste'); $self->{taste} = $_[0]; } return $self->{taste}; } sub all { my $self = shift; my @values = @$self{qw( color texture taste )}; return join("\t", @values); } 1; #### #!/usr/bin/perl -w use strict; use HistoryObj; my $hist = HistoryObj->new(); my $hist2 = HistoryObj->new(); $hist->color('pink'); $hist->texture('cotton candy'); $hist->taste('sweet'); print $hist->all(), "\n\n"; $hist2->color('beet purple'); $hist2->texture('slimy round goo'); $hist2->taste('do not ask!'); print $hist2->all(), "\n\n"; for (1 .. 3) { $hist->undo(); print $hist->all(), "\n\n"; } for (1 .. 3) { $hist2->undo(); print $hist2->all(), "\n\n"; }