Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Strange behavior with "local" Keywords: local bug Message-ID: <7470@jpl-devvax.JPL.NASA.GOV> Date: 20 Mar 90 00:43:11 GMT References: <1363@frankland-river.aaii.oz.au> <1364@frankland-river.aaii.oz.au> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 67 In article <1364@frankland-river.aaii.oz.au> pem@frankland-river.aaii.oz.au (Paul E. Maisano) writes: : However, this does demonstrate that due to the way local works you : must be careful about naming your 'local' variables if you are modifying : your arguments. The scenario is: : You have a global variable called $buf. : It calls a subroutine which alters $buf (by reference). : [The subroutine knows nothing about the name of the variable.] : The subroutine has a 'local' variable called $buf. : When the subroutine exits, the old value of $buf is restored since : we are no longer in the scope of the 'local'. : Thus the new value of $buf is overwritten by the old value. : This seems IMVHO to be a misfeature, if the names of local variables : can affect the way the program runs. It's never a problem unless you modify parameters passed by reference, which is a slightly dangerous thing in almost anyone's book. But here's a way to do it. It almost looks idiomatic, though the necessity for double brackets I would consider to be a bug: #!/usr/bin/perl $buf = "original value"; &buggy($buf); print "buf=$buf\n"; sub buggy { $_[0] = do {{ local($buf) = "new value"; print "buf=$buf\n"; $buf; }}; } : Isn't there any safer way to implement local variables. Static scoping ? : I'd make some suggestions but I'm already too embarrassed by my last posting. Some measure of static scoping is provided by the package declaration. Perhaps that is what you want. Now you only have to worry about package name collisions... However, picking one unique name for a package is a lot easier than picking unique names for all your local variables, if you're going to be doing a lot of reference parameter modification. And it lets you have a package of routines that can keep its own state between subroutine calls. Since all characters of a package name are significant, you would be pretty safe in saying: #!/usr/bin/perl $buf = "original value"; &buggy($buf); print "buf=$buf\n"; sub buggy { package jaksopfqjiwofkslfdjkasljfklqowjedfikaxjajksdjfkalqpmvcmvxo; local($buf) = "new value"; print "buf=$buf\n"; $_[0] = $buf; } Randal would probably just say $buggy'buf all over. But it's easier to use the package declaration. Especially if you use the package name above. :-) Larry