Delete *really* means delete
Simon Wistow
simon at thegestalt.org
Thu Feb 24 18:35:30 GMT 2011
I'm idly playing around with some Model type code yesterday wondering if
I could make the delete method *really* delete itself.
The use case I'm worried about is something like
my $foo = Foo->new;
... do some stuff ...
$foo->delete; # it's now gone from the database
... time passes ...
$foo->bar("some value"); # Whoops, they really shouldn't be doing this
$foo->save; # Now we're in a really bad state
There's some obvious techniques - setting a flag on delete or overriding
DESTROY to be
sub DESTROY { shift->delete }
and then requiring
undef $foo
But I was wondering if I could get delete to eat itself whole.
----- >8 -----
% cat delete.pl
foreach my $meth qw(delete_hash empty_hash delete_ref
undef_at_underscore) {
my $foo = Foo->new;
eval { $foo->$meth };
print "After $meth \$foo is ".(defined $foo ? "undead" : "dead");
chomp($@) && print " (Error: $@)" if $@;
print "\n";
}
package Foo;
sub new { return bless {}, shift }
sub delete_hash {
my $self = shift;
undef %$self;
}
sub empty_hash {
my $self = shift;
%$self = ();
}
sub delete_ref {
my $self = shift;
$$self = undef;
}
sub undef_at_underscore {
$_[0] = undef;
}
1;
% perl delete.pl
After delete_hash $foo is undead
After empty_hash $foo is undead
After delete_ref $foo is undead (Error: Not a SCALAR reference at
delete.pl line 28.)
After undef_at_underscore $foo is dead
%
----- >8 -----
I was pretty sure I couldn't do $$self = undef because $self isn't a
SCALAR necessarily. %$self = () would just leave an empty array around.
I'm convinced that I tried $_[0] = undef last night and it didn't work
but now it seems to work. Which is weird.
Other suggestions were reblessing $self into 'DEAD' and then having
package DEAD;
use Carp qw(confess);
sub AUTOLOAD { confess "This object is dead" }
1;
Any other suggestions?
More information about the london.pm
mailing list