Perhaps I'm too much of a C++ hacker, but I tend to use this capability heavily. Consider a Foo::Lock class which implements a lock on a Foo, where foo might be a file, database record, etc. Then, your methods inside Foo.pm can be made "safe" by code like:
sub do_something()
{
my $obj = shift @_;
my $crit = new Foo::Lock( $obj );
$crit->lock();
# now do something in the critical section ...
$obj->yada_yada();
return unless $obj->valid();
# now do some more stuff...
$obj->yada_yada();
return( $result );
}
In this case, we don't have to free the Lock explicitly, because its DESTROY method does that automagically. And we are never left with a hard-to-track deadlock defect because our app took a fatal somewhere, leaving the Foo accidentally locked. On the other hand, if $crit were cleaned up soonest, we couldn't depend on the critical section being held for as long as we need it.