John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

This doesn't work:
my $result= do { $result += $_ foreach (@items) };
because $result isn't defined inside the do block. Yet, something like read (FH, my $buffer, 999) works just fine, even though this would seem to be the same situation: the variable is defined inside the expression where it is used.

It sounds more like a lexer issue, in that the name isn't known elsewhere in the expression, even though the variable is in fact defined! I've not explored that hypothosis, but wonder if anyone already knew.

—John

Replies are listed 'Best First'.
Re: when does the definition of a my variable take effect?
by Aristotle (Chancellor) on Aug 23, 2002 at 03:04 UTC

    After the my statement is executed. In the read FH, my $buffer, $len case, you're using my as an lvalue, while in the posted snippet, you try to use the variable as an rvalue before the my has executed.

    Update: D'oh! Brainfart. I said rvalue where it's an lvalue and vice versa. Post fixed.

    Makeshifts last the longest.

      What makes $buffer an rvalue? It is modified by the call to read, so it must be an lvalue.
Re: when does the definition of a my variable take effect?
by sauoq (Abbot) on Aug 23, 2002 at 03:09 UTC
    I don't think you can use it in the initialization EXPR. A simpler example than yours: my $result = $result + 1; wouldn't work either. But, there is no problem using it as an EXPR inside another one (as in your read() example.) I don't think: read(FH, my $buf = $buf . "foo", 512, 3) would work either.
    -sauoq
    "My two cents aren't worth a dime.";
    
      Or my favourite:

      chomp(my $var = <STDIN>);

      --
      Until you've lost your reputation, you never realize what a burden it was or what freedom really is. -Margaret Mitchell

Re: when does the definition of a my variable take effect?
by particle (Vicar) on Aug 23, 2002 at 14:07 UTC
    you'll have to do something like
    #!/usr/bin/perl use strict; use warnings; print my $r = do { my $r; $r += $_ for 1..3; $r }
    to get what you want to run under strict and warnings.

    from the manual...

    > perldoc -f do
        do BLOCK
                Not really a function. Returns the value of the last command in
                the sequence of commands indicated by BLOCK. When modified by a
                loop modifier, executes the BLOCK once before testing the loop
                condition. (On other statements the loop modifiers test the
                conditional first.)
    
                "do BLOCK" does *not* count as a loop, so the loop control
                statements "next", "last", or "redo" cannot be used to leave or
                restart the block. See perlsyn for alternative strategies.
    
    <snip>
    

    you're executing a code block within do -- with a new scope. you'll need a my'd var there. also, you need to explicitly list the variable as the last statement in the block, in order to return the proper value.

    ~Particle *accelerates*

Re: when does the definition of a my variable take effect?
by rinceWind (Monsignor) on Aug 23, 2002 at 09:25 UTC
    The problem with $result would have been found by use strict;.

    The technique of allowing strict to find scoping problems has become second nature - catching bugs before they happen. Similarly, use warnings; can catch uninitialised variable bugs.