Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

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

by jeffa (Bishop)
on Aug 06, 2003 at 17:23 UTC ( [id://281510]=note: print w/replies, xml ) Need Help??


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

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? ;)

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)

Replies are listed 'Best First'.
Re: Re: Anti-snippet (or, "local" considered dangerous to fools")
by Juerd (Abbot) on Aug 06, 2003 at 17:29 UTC

    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 => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: Re: Anti-snippet (or, "local" considered dangerous to fools")
by Mur (Pilgrim) on Aug 08, 2003 at 16:05 UTC
    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
     http://www.nexcerpt.com
    ...Nexcerpt...Connecting People With Expertise

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://281510]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (8)
As of 2024-04-18 14:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found