http://qs321.pair.com?node_id=255670


in reply to Toggling between two values

Your "closure" sub isn't actually a closure; to be a closure it would not only have to access outside lexicals (like yours does), but also be anonymous. What you have works anyway because you don't attempt to have several independent swap subs each of which has its own private state.

BTW, the reason why this doesn't work: $result =  $head. " er glad " . $result while( my $head = &swap ); ... is that the parsing works left-to-right, and so $head has to be declared by the point where it is first seen in scanning, not where it would first be touched in execution.

    -- Chip Salzenberg, Free-Floating Agent of Chaos

Replies are listed 'Best First'.
•Re: Re: Toggling between two values
by merlyn (Sage) on May 05, 2003 at 17:24 UTC
    Your "closure" sub isn't actually a closure; to be a closure it would not only have to access outside lexicals (like yours does), but also be anonymous.
    No, "closure" and "named" are orthogonal properties. In the following, the named subroutine gimme is a closure:
    BEGIN { my $number = 0; sub gimme { ++$number; } }
    Yes, there's some Perl literature that mixes up the two concepts of anonymous and closure because they are often correlated, but really they are separate properties.

    Although I do feel a bit weird correcting chip on this point. {grin}

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

      "closure" and "named" are orthogonal properties

      I'm afraid that's not quite true, at least in Perl. Perl subs that are named are not closures, by fiat. This choice was made to prevent imposing closure overhead on subroutines that don't need closure behavior (i.e. the capturing of values at time of sub reference).

      The rule, as best I recall, is: In Perl, a closure is an anonymous subroutine that accesses at least one lexical variable not declared at global scope. BTW, IIRC, BEGIN blocks are deemed to be global scope for the purpose of deciding whether a sub is a closure.

      I do feel a bit weird correcting chip on this point.

      Well, you should, since you're wrong. {grin}

          -- Chip Salzenberg, Free-Floating Agent of Chaos

        But I thought the "not stay shared" error is because the closure stuff is triggering on a named subroutine (usually inside another one). Is that not being closed on the first invocation, and subsequent invocations creating different lex vars?

        And, on a completely different note, is this not a named closure?

        my $coderef = do { my $counter = 0; sub { ++$counter }; }; *named_closure = $coderef;
        That looks like I can call named_closure() to me, and it's a named closure.

        Perhaps that's not what

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

        I'm afraid that's not quite true, at least in Perl.
        Then Perl has it wrong.
        Perl subs that are named are not closures, by fiat.
        By fiat? Of whom? ;-)

        Merlyn has it right: being a closure and being named are orthogonal properties. OTOH, I'm not saying you are wrong, because you have experience in a strange, quantum-like world (aka perl internals) where the normal definitions don't necessarily apply.

        jdporter
        The 6th Rule of Perl Club is -- There is no Rule #6.