in reply to Re: Local $$_?
in thread Local $$_?

Good morning. Thanks for your reply. local @::{@names}; Does infact work, however is there a way to also assign the previous value at the same time? Similar to local $$_ = $$_;?

Replies are listed 'Best First'.
Re^3: Local $$_?
by Corion (Patriarch) on Mar 15, 2010 at 11:13 UTC
    local @::{@names} = @::{@names}

    should carry over the values, but on this 5.10.0, it exhibits inconsitent behaviour:

    Saving the values keeps the localizing behaviour:

    >perl -le "@l=qw(a b c);$b=3;do{my@v=@::{@l};local @::{@l};print $b;$b +=2;print $b};print $b" 2 3

    "Resetting" the values destroys the localizing behaviour:

    >perl -le "@l=qw(a b c);$b=3;do{my@v=@::{@l};local @::{@l}=@v;print $b +;$b=2;print $b};print $b" 3 2 2

    The same failure with the direct assignment:

    >perl -le "@l=qw(a b c);$b=3;do{local @::{@l} = @::{@l};print $b;$b=2; +print $b};print $b" 3 2 2

    I would consider this inconsistency a bug, but maybe it's already fixed in 5.10.1 or 5.11.

    This is perl, v5.10.0 built for MSWin32-x86-multi-thread Copyright 1987-2007, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. G:\Aktivitaeten\IDV\wp2-XML-sst\OUTPUT>perl -V Summary of my perl5 (revision 5 version 10 subversion 0) configuration +: Platform: osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und +ef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DPERL_IMPL +ICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -DPERL_M SVCRT_READFIX', optimize='-s -O2', cppflags='-DWIN32' ccversion='', gccversion='3.4.5', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long lo +ng', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='g++', ldflags ='-s -L"G:\Systeme\Tools\Perl-5.10.0\perl\lib\CO +RE" -L"G:\Systeme\Tools\Perl-5.10.0\c\lib"' libpth=C:\strawberry\c\lib libs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool - +lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 - luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 perllibs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspo +ol -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi 32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 libc=-lmsvcrt, so=dll, useshrplib=true, libperl=libperl510.a gnulibc_version='' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-mdll -s -L"G:\Systeme\Tools\Perl-5.10. +0\perl\lib\CORE" -L"G:\Systeme\Tools\Perl-5.10.0\c\lib"' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS USE_LARGE_FILES USE_PERLIO Built under MSWin32 Compiled at Dec 21 2007 14:11:41 @INC: g:/Systeme/tools/perl-5.10.0/perl/lib g:/Systeme/tools/perl-5.10.0/perl/site/lib .
      > local @::{@names} = @::{@names}

      I suppose the problem you're experiencing is not really a bug but due to the fact that a slice on the stash deliveres globs not values:

      DB<1> ($a,$b)=qw/A B/ DB<2> @n=qw/a b/ DB<3> @save=@::{@n} DB<4> x @::{@n} 0 *main::a 1 *main::b DB<5> x @save 0 *main::a 1 *main::b

      initializing the localized vars should be done with the _values_ not with the globs. In this way you are "re-aliasing" the package vars to the old ones!

      But I'm not enough of a perl4 expert for details... ;)

      Cheers Rolf

      UPDATE: to be more precise, your code above should be equivalent to something like

      local (*a,*b) = (*a,*b)

      and not

      local ($a,$b) = ($a,$b)

      I observe the same behavior with v5.11.1-4-gfb35b2c* built for MSWin32-x86-multi-thread
Re^3: Local $$_?
by Anonymous Monk on Mar 15, 2010 at 11:14 UTC
    local @::{@names} = @::{@names};
    I fear your reasons for doing this
Re^3: Local $$_?
by LanX (Saint) on Mar 15, 2010 at 12:01 UTC
    Now you can use a loop or a temporary array to set whatever values you want!

    Cheers Rolf

      Thank you LanX! You're correct in assuming this will be used in a loop. An FCGI Loop infact. Some older scripts were not designed with lexicallity in mind and simply make use of global variables if and when they're values are needed. Localizing these at the beginning of the FCGI Loop allowed me to run the given program under FCGI without re-writing it. Early indications show an improvement of over 500%. Although it is not a perfect solution - it seems to be working.
        Yeah I was expecting something like reusing old code.

        Glad if I was able to help! :)

        Cheers Rolf

        UPDATE: But you should do thorough testing to be sure about the side-effects! Be aware: In many cases testing and fixing resulting bugs aren't cheaper than rewriting ...

        Using lexical variables are almost always better!

        All you really needed was

        print "local \$$_ = \$$_;\n" for @listofvarnames;
        then you copy/paste
        local $blah = $blah; ...

        Although it is not a perfect solution - it seems to be working.

        The use of global variables is red flag. Your statement that "it seems to be working" also indicates that it doesn't come with a test suite, another red flag. I think now is a time to consider/plan to refactor this program.

        > You're correct in assuming this will be used in a loop.

        Maybe a misunderstanding, in the OP you were trying to localize package vars in a loop, this can't be done because of the loop scope.

        But of course you are free to initialize the vars in a loop or a list assign _after_ you localized them.

        Cheers Rolf