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