http://www.perlmonks.org?node_id=779030


in reply to Re^2: Mini-Tutorial: Working with Odd/Even Elements
in thread Mini-Tutorial: Working with Odd/Even Elements

Too golfy or arcane? (fixed now)
sub map_pairs(&@) { my $fn = shift; my $pkg = $main::{caller().'::'}; map { @{$pkg}{qw(a b)} = \(@_[0,1]); $fn->(shift, shift); } (0..$#_/2); } package Smarter; our($a, $b) = qw(orig value); my @arr = qw(a b c d); print main::map_pairs {$_[0] = uc($a); print "[$a $_[1]]\n"; $a} @arr; print "\n"; print "Now @arr\n"; print "\n$a $b\n";
I like being able to avoid sym refs and all the globbage. The interesting thing to note is that I seem to get a magical localization of my variables.

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^4: Mini-Tutorial: Working with Odd/Even Elements
by ikegami (Patriarch) on Jul 10, 2009 at 20:14 UTC

    Too golfy or arcane?

    All of these map_pairs implementations are in the red zone of the arcanometer.

    The interesting thing to note is that I seem to get a magical localization of my variables.

    Array elements aren't lexical variables, if that's what you're talking about.

    As for using local on array elements, perlsub says

    Some types of lvalues can be localized as well : hash and array elements and slices, conditionals (provided that their result is always localizable), and symbolic references. As for simple variables, this creates new, dynamically scoped values.

    That means

    my @a; local $a[0]; # Not a problem my %a; local $a{k}; # Not a problem
      Array elements aren't lexical variables, if that's what you're talking about.
      No, I was saying that my "orig value" came back without my making them local (see the other reply to my node), but apparently that's not a reliable feature. I was using ActivePerl, for the record.

      Caution: Contents may have been coded under pressure.
        Oh! I thought you were using
        local @{$pkg}{qw(a b)} = \(@_[0,1]);
        rather than
        @{$pkg}{qw(a b)} = \(@_[0,1]);

        I can reproduce that bug with

        This is perl, v5.8.8 built for MSWin32-x86-multi-thread (with 12 registered patches, see perl -V for more detail) Binary build 824 [287188] provided by ActiveState http://www.ActiveSta +te.com Built Sep 3 2008 11:14:55
        but not with
        This is perl, v5.8.0 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Binary build 806 provided by ActiveState Corp. http://www.ActiveState. +com Built 00:45:44 Mar 31 2003
        This is perl, v5.10.0 built for MSWin32-x86-multi-thread (with 5 registered patches, see perl -V for more detail) Binary build 1004 [287188] provided by ActiveState http://www.ActiveSt +ate.com Built Sep 3 2008 13:16:37
        or
        This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
Re^4: Mini-Tutorial: Working with Odd/Even Elements
by LanX (Saint) on Jul 10, 2009 at 21:16 UTC
    The interesting thing to note is that I seem to get a magical localization of my variables.
    that's the output I get
    [A b] [C d] AC Now A b C d C d
    "orig" and "value" are lost, so no "magical localization". but adding local
        local @{$pkg}{qw(a b)} = \(@_[0,1]);
    produces
    [A b] [C d] AC Now A b C d orig value

    Cheers Rolf

    UPDATE:This was perl, v5.10.0 built for i486-linux-gnu-thread-multi
      That's what I would have expected. Thanks for the data point. I was wondering whether there was some obscure documented reason it should behave as I was seeing.

      Caution: Contents may have been coded under pressure.
Re^4: Mini-Tutorial: Working with Odd/Even Elements
by ikegami (Patriarch) on Jul 16, 2009 at 18:32 UTC

    By the way, your fixed is still broken. It only works if the calling package is one level away from the root. If the caller is Foo, it works. If the caller is Foo::Bar, it doesn't.

    Using a symbolic ref is simpler than using %::.

    my $pkg = do { no strict 'refs'; *{caller().'::'} };