[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