For the first time I used
Scope::Guard
and I like the idea.
I used it to always issue database rollback if something goes wrong, some
exception, in DBIx::Class ResultSet function. Then when calling this function
I can wrap it in eval {};
block and don't need to care about
the begin/commit/rollback stuff.
sub do_some_database_stuff : ResultSet { my $rs = shift; # begin transaction $rs->result_source->schema->txn_begin;
# trigger rollback if we leave the function unexpecticly my $make_sure_we_rollback = Scope::Guard->new(sub{ local $@; # we don't want txn_rollback to mess up the $EVAL_ERROR $rs->result_source->schema->txn_rollback; });
# # insert, deletes, updates ... #
# commit transaction when all passed $rs->result_source->schema->txn_commit; $make_sure_we_rollback->dismiss; return $some_created_rows; }
I think that any module doing things similar to Scope::Guard (Perl::AtEndOfScope, etc) that doesn't deal with, or even mentions, the risks with eval/die isn't really doing its job.
I say this because it's not really obvious that there might be a problem, but the consequences when things go wrong are subtle and dire (silenced exceptions go untrapped).
Dealing with exceptions being thrown is simply a complication inherent to the problem being solved.
(btw Perl::AtEndOfScope does this correctly now)
I wrote ReleaseAction years ago. ReleaseAction was not the first - Abigail wrote End well before I wrote that. And now I've just learned of 2 more modules that do the same thing!
Re:How many times has this been written?
jozef on 2008-07-18T07:50:56
Well there are just too many modules in CPAN... The Scope::Guard was shown in "Perl Hacks: Tips & Tools for Programming, Debugging, and Surviving" book as hack #88.
In the "See Also" of Scope::Guard there are even more of "those kinds" - Hook::LexWrap, Hook::Scope, Sub::ScopeFinalizer, Object::Destroyer
... Which one is the "best"?