Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Anti-snippet (or, "local" considered dangerous to fools")

by Mur (Pilgrim)
on Aug 05, 2003 at 20:00 UTC ( #281143=snippet: print w/ replies, xml ) Need Help??

Description: Don't do this. It makes for long, painful debugging sessions.
Instead of:
local($object1->{field}) = $val;
local($object2->{field}) = $val;
local($object3->{field}) = $val;
That's too much typing! Instead,
for ($object1,$object2,$object3) {
  local($_->{field}) = $val;
So much nicer to look at, but completely, utterly wrong.
Comment on Anti-snippet (or, "local" considered dangerous to fools")
Select or Download Code
Replies are listed 'Best First'.
Re: Anti-snippet (or, "local" considered dangerous to fools")
by jeffa (Bishop) on Aug 06, 2003 at 17:23 UTC
    Indeed. Reserve the use of local for Perl built-in vars, for example:
    my $file_contents_as_scalar = do{local $/;<FILEHANDLE>};
    This "temporarily" undefines $/ so that the entire file handle is read into a scalar without resorting to appending inside a while loop.

    Using local on lexical or package variables can be dangerous. For your example, surely the better way to assign that variable to multiple classes is:

    $_->{field} = $var for @object;
    You did store your objects in a container didn't you? ;)


    (the triplet paradiddle with high-hat)

      Using local on lexical or package variables can be dangerous.

      You can reduce that to:
      "Using local can be dangerous."

      See also Coping with Scoping. In short: don't use local on variables not mentioned in perlvar. Do use local on variables mentioned in perlvar.

      Juerd # { site => '', plp_site => '', do_not_use => 'spamtrap' }

      Well, I would agree that local is to be avoided where possible, but it's rather hard in this case:
      sub main_loop { local($dbh->{AutoCommit}) = 0; ... lots of code here, with multiple returns }
      To avoid a problem with DBD::Pg, I have all my database connection handles set to "AutoCommit" (otherwise, they start a new transaction after every COMMIT; daemons thus hold open transactions for hours at a time, waiting for the next request). I turn the AutoCommit setting off just before starting to process something. I could turn it back on, but I'd have to put that before each and every return statement. Making a lexical copy of the object doesn't help:
      my $tmp_dbh = $dbh; $tmp_dbh->{AutoCommit} = 0; #BZZT!
      because they're handles, what you do to one affects all the copies. What I really need is a continue block for subroutines ...
      # Wishful thinking sub main_loop { ... stuff happens ... } continue { ... oops! I must have returned! }
      Perhaps I could do this with a naked block?
      sub main_loop { { ... stuff happens ... ... use 'last' instead of 'return'? } ... restore settings here }
      but local for all its shortcomings, is much easier to understand by the next guy (or is it?). As to the idea of a container: no, but not applicable in this case. One object is the return value of a subroutine (and is a package variable from elsewhere), the other is a package variable in the current package.
      Jeff Boes
      Database Engineer
      Nexcerpt, Inc.
      vox 269.226.9550 ext 24
      fax 269.349.9076
      ...Nexcerpt...Connecting People With Expertise

Back to Snippets Section

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://281143]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2016-02-13 11:22 GMT
Find Nodes?
    Voting Booth?

    How many photographs, souvenirs, artworks, trophies or other decorative objects are displayed in your home?

    Results (427 votes), past polls