[Melbourne-pm] Closures and scope warnings
Toby Corkindale
toby.corkindale at strategicdata.com.au
Wed Jul 28 01:01:27 PDT 2010
On 28/07/10 14:01, Damian Conway wrote:
> Jacinta observed:
>
>> Would you *really* want every subroutine which creates variables which
>> shadow top-level variables to warn about such? I don't think Perl
>> distinguishes between your case and mine.
>
> It doesn't even distinguish this case:
>
> my $name = "Jacinta";
>
> {
> my $name = 'shift';
>
> print "$name\n";
> }
>
> The whole point of lexical scope is that variables declared inside a
> block hide identically named variables declared outside the block. It
> doesn't matter if the block is "raw" (as above) or is the body of a
> named subroutine (like Jacinta's example), or the body of an unnamed sub
> (like Toby's example).
Thinking about my example some more (the transaction block for
DBIx::Class), I'm coming around to the opinion that it must be bad
practice to alter external variables. The transaction could fail, which
will rollback the changes to DB-tied objects, but not the external
variables.
Consider this somewhat contrived example:
my $person = get_person_from_db();
my $new_salary = get_new_salary_from_api();
my $weekly_pay; #undef
eval {
$schema->txn_do(sub {
$person->salary($new_salary);
my $weekly_pay = $person->salary / 52;
$external_payments_api->set_weekly_pay($person->id, $weekly_pay);
$person->update; # Fails in DB for some reason
});
};
if ($@) {
say "Whoops, something went wrong."
}
say "Your salary is " . $person->salary . " with weekly pay of $weekly_pay."
The problem being that the external factors weren't rolled back on an
error, so the external payments API would still have been updated with
the new salary here. Obviously, bad practice and you're an idiot if you
do this.. but it makes me wonder if the whole thing of modifying
external non-db stuff during the transaction is bad.
(Another problem being if, say, the external_payments_api interface
hangs for minutes, locking up the db for that user's record in the
meantime.)
More information about the Melbourne-pm
mailing list