in reply to map()'s BLOCK and deviations from othogonality...

Updated (per local argument on clarity):
You are in map()'s EXPR form and so are not seeing the real problem.

Disambiguate your expression:

my %hash=map { ; # Disambiguator no strict 'refs'; $_ => \&{$_}; } qw/sol1 sol2 .../;
Be well,
rir

Replies are listed 'Best First'.
Re^2: map()'s BLOCK and deviations from othogonality...
by blazar (Canon) on Feb 24, 2005 at 16:33 UTC
    You are in map()'s EXPR form and so are not seeing the real problem.

    Disambiguate your expression:

    my %hash=map { ; # Disambiguator
    Hmmm, I see that this does work. So basically you're saying that if don't put that disambiguator there, perl thinks it's the EXPR form of map() rather than the BLOCK form, notwithstandig the fact that there's no comma after the block itself. I think this is so because it begins to interpret the "no" as a hash(ref)'s key, right?

    All in all one the lesson we learn could be that "while nothing but perl can parse Perl, even perl sometimes has difficulties doing so"...

      This is even documented in perlref:
      Because curly brackets (braces) are used for several other +things including BLOCKs, you may occasionally have to disambiguate + braces at the beginning of a statement by putting a "+" or a "retu +rn" in front so that Perl realizes the opening brace isn't startin +g a BLOCK. The economy and mnemonic value of using curlies is +deemed worth this occasional extra hassle. For example, if you wanted a function to make a new hash an +d return a reference to it, you have these options: sub hashem { { @_ } } # silently wrong sub hashem { +{ @_ } } # ok sub hashem { return { @_ } } # ok On the other hand, if you want the other meaning, you can d +o this: sub showem { { @_ } } # ambiguous (currently o +k, but may change) sub showem { {; @_ } } # ok sub showem { { return @_ } } # ok The leading "+{" and "{;" always serve to disambiguate the +expres- sion to mean either the HASH reference, or the BLOCK.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        This is even documented in perlref:
        You're right! (What else?!?)

        I'm also ashamed, since I had read that section sometimes... OTOH retrospectively I'm slightly surprised that at least a few experienced perl hackers from clpmisc didn't recognize it at a first glance either...

        Because curly brackets (braces) are used for several other things including BLOCKs, you may occasionally have to disambiguate braces at the beginning of a statement by putting a "+" or a "return" in front so that Perl realizes the opening brace isn't starting a BLOCK. The economy and mnemonic value of using curlies is deemed worth this occasional extra hassle.
        Hmmm, it seems that the docs concentrate on the somewhat opposite situation, i.e. that in which a hashref is mistaken for a block.
        The leading "+{" and "{;" always serve to disambiguate the expres- sion to mean either the HASH reference, or the BLOCK.
        I must say that while I find "+{" aesthetically appealing, I can't say the same of "{;". But of course that's just me...
      So basically you're saying that if don't put that disambiguator there, perl thinks it's the EXPR form of map() rather than the BLOCK form, notwithstandig the fact that there's no comma after the block itself.

      That can't be. Indeed, Perl does make the decision before it is even close to worrying about the comma, but the comma must be there for an expression and must not be there for a block.

      So if you and Perl disagree on the expression vs. block interpretation, then the presense or lack of the comma will cause Perl to tell you quite loudly that it didn't agree with you (unless you get the comma's existence wrong compared to your desire for the expression vs. block form).

      So I've been assuming that one side or the other of this discussion hasn't actually tested the exact code under discussion. No, I haven't tested any of it.

      - tye        

        It seems clear that Perl guesses an expression and then chokes on the "no" before finding the end of the expression.
        my %hash=map { no strict 'refs'; $_ => \&{$_}; } qw/sol1 sol2 .../; # Pseudo-code
        __END__ "no" not allowed in expression at x line 4, at end of line BEGIN not safe after errors--compilation aborted at x line 4.

        Be well,
        rir