in reply to Type globs, strict, and lexical variables

I think you are looking for:

{ local *bar # Make sure we don't clobber an existing var. *bar = \@foo; # Create an alias our @bar; # So we don't have to say @Package::bar. print($bar[0]); # Same as print($foo[0]); } # Restores *bar (and therefore $bar, @bar, etc)

The first two lines can be combined:

local *bar = \@foo;

Alternativly, Data::Alias allows one to lexical aliases.

Replies are listed 'Best First'.
Re^2: Type globs, strict, and lexical variables
by cems2 (Novice) on Jul 17, 2006 at 05:33 UTC
    Cool! never would have thought I could localize a typeglob itself. Hmmmm... will this really work, since you can't localize a variable that doesn't pre-exist, under strict.
      you can't localize a variable that doesn't pre-exist, under strict.

      That's not true. strict has nothing to do with local. For example,
      perl -Mstrict -e "local $Package::foo"
      give no error.
      perl -Mstrict -e "local $foo"
      gives an error, but so does
      perl -Mstrict -e "$foo"

      will this really work

      Strict doesn't apply to globs (since they can't be declareds), so
      perl -Mstrict -e "*foo"
      and
      perl -Mstrict -e "local *foo"
      give no error.

Re^2: Type globs, strict, and lexical variables
by cems2 (Novice) on Jul 17, 2006 at 05:42 UTC
    yep! this works like a charm.
    perl -we 'use Strict; our $r="foo"; my $f = "boot";{local *r =\$f; $r += "loop"; print "$f\n$r\n...\n"};print print "$f\n$r\n...\n"' __output__ loop loop ... loop foo ...
    Thanks a lot. I learned something interesting.
Re^2: Type globs, strict, and lexical variables
by cems2 (Novice) on Jul 17, 2006 at 13:38 UTC
    I spoke too soon. using local still soes not present accidental clobbering:
    my $f = "boot"; {local *tmp =\$f; $tmp = "loop"; GG::cc () ;print "$f\n...\n"}; sub cc { $tmp="cc did it"}; print "$f\n...\n";
    sub cc, happens to use the same dummy variable name $tmp. as a result as the local expression $f gets clobbered. What I want is something that makes $tmp scoped like a my variable.

    THe problem I am trying to solve here is simply to always have to write de-reference code when I pass in a reference. I want an alais in the form of a localy scoped variable to the object being dereferenced. It looks like you might be able to do this with a tie or with Data::alias but those are both very heavyweight solutions.

      strict won't let you do that.
      use strict; sub test { my $f = "boot"; local *tmp = \$f; print("$tmp\n"); # boot our $tmp = "loop"; print("$tmp\n"); # loop test2(); print("$tmp\n"); # loop } sub test2 { #$tmp = "test2 did it"; # XXX strict error my $tmp = "test2 did it"; # lex var alternative local our $tmp = "test2 did it"; # pkg var alternative } test();

      Yes, test2 can change the value of $tmp, but only if test2 doesn't properly localize its variables. Perl gives you plenty of ways of shooting yourself in the foot, but they can all be avoided easily and safely with a little care. In this case, that means local shoule be used whenever our is used, unless there is a need to modify the variable in the parent scope.

      Data::Alias isn't that heavyweight I think... I know it's a bit largeish module, but unlike tie() its use imposes virtually no overhead at runtime, and very little at compile time (no source filter).

      And it solves your problem nicely, and probably more efficiently than anything involving typeglobs:

      alias my @bar = @$foo;

      UPDATE: It actually benchmarks faster than local *bar = $foo on my machine, with the benefit of being truly lexically scoped.

      sub cc, happens to use the same dummy variable name $tmp.
      But dummy variables should always be lexicals. In fact, I don't think you've absorbed the concept that everything possible (which is just about everything) should be lexical. Are you dealing with legacy code?