in reply to Re: syntax of map operator
in thread syntax of map operator

I since discovered that both versions add a scope.
Yes, but they aren't the same scopes. The EXPR variant doesn't create a lexical scope; the BLOCK variant does:
$ perl -Mstrict -wcE 'my @x = map my $x = $_, 2; say $x' -e syntax OK $ perl -Mstrict -wcE 'my @x = map {my $x = $_} 2; say $x' Global symbol "$x" requires explicit package name at -e line 1. -e had compilation errors.
I'm not quite sure what kind of scoping effects happen.
$ perl -Mstrict -wE 'my @x = map my $x = $_, 2; say $x' Use of uninitialized value $x in say at -e line 1. $ perl -Mstrict -wE 'my $x; my @x = map $x = $_, 2; say $x' 2
So, if we declare $x in the first argument of map, $x exists afterwards, but doesn't have a defined value. If declared before the map, it keeps the last assigned value.

I guess that's more an artifact of the implementation than that it was designed to work this way.

Replies are listed 'Best First'.
Re^3: syntax of map operator
by ikegami (Patriarch) on Jan 24, 2010 at 19:01 UTC

    I guess that's more an artifact of the implementation than that it was designed to work this way.

    I fully agree. Compile-time lexical scopes and run-time lexical scopes should be the same. All of these are in the same bag:

    • my $x if ...;
    • my $x for ...;
    • map my $x, ...;
    • ... and my $;x

    Just don't.

      I'm very glad EXPR if COND doesn't provide a lexical scope. That allows me to write:
      local $dbh->{AutoCommit} = 0 if !$already_in_a_transaction;
      I once had a cow orker (who thinks he's one of the smartest programmers in the world) rewrite that as
      if (!$already_in_a_transaction) { local $dbh->{AutoCommit} = 0; }
        You should wrap one more if around that just to be sure.