Delete *really* means delete

Simon Wistow simon at
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

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;


% perl

After delete_hash $foo is undead
After empty_hash $foo is undead
After delete_ref $foo is undead (Error: Not a SCALAR reference at 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" }


Any other suggestions?

More information about the mailing list