Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

difference between 'if (condition) { expression;}' and 'expression if (condition)'

by ranjan_jajodia (Monk)
on Mar 22, 2006 at 14:24 UTC ( #538512=perlquestion: print w/replies, xml ) Need Help??

ranjan_jajodia has asked for the wisdom of the Perl Monks concerning the following question:

This is probably a simple question but I am unable to find the answer on the internet because the term involved ('if') is very general.
use strict; if (@_) { my $var = "ok"; } print "$var\n";
The above code throws the following (expected) error :
Global symbol "$var" requires explicit package name at line 6 +. Execution of aborted due to compilation errors.
But, example 2:
use strict; my $var = "ok" if (@_); print "$var\n";
does not.
Could any one please explain the difference between the two usage?

UPDATE: I think it might be because of the braces which puts the $var in a inner namespace. Am I right?

Replies are listed 'Best First'.
Re: difference between 'if (condition) { expression;}' and 'expression if (condition)'
by ww (Archbishop) on Mar 22, 2006 at 14:31 UTC

    In your first example, $var is declared inside the if block, but exists ONLY within that block. Since it's undefined when program_flow encounters the print statement, strict pumps out the error.

    On the other hand, in your example 2, "my $var" is in scope throughout the code you show.

      Careful with my $var if $condition. From perlsyn:

      NOTE: The behaviour of a "my" statement modified with a statement modifier conditional or loop construct (e.g. "my $x if ...") is undefined. The value of the "my" variable may be "undef", any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.


      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        Thanks xdg. I won't use. I saw something similar in an existing code and I was surprised that it works. Hence I decided to prod a bit.

      The second example is also buggy and shouldn't be used. Declare the variable in the previous line. The bug is that the runtime effect of my() is avoided when the condition fails.

      my $var; $var = 'ok' if @_;

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      Thanks ww.
      Since the second example works fine which means that even though the expression is not executed because of the condition being false, still the variable is declared. Is it like the perl interpreter first parses the code for the declared variables and their scope and then starts executing the code?
Re: difference between 'if (condition) { expression;}' and 'expression if (condition)'
by ptum (Priest) on Mar 22, 2006 at 14:41 UTC

    Note, however, that if you had warnings on (use warnings;), you would have seen something like this when executing example 2:

    Use of uninitialized value in concatenation (.) or string at ./ + line 5.

    This is because you refer to a value ($var) which, while it is within the current scope, has never been set to any value (it is still undef). I find that such warnings are often an indicator that my code is doing something I don't expect or haven't prepared for.

    No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: difference between 'if (condition) { expression;}' and 'expression if (condition)'
by pKai (Priest) on Mar 22, 2006 at 20:04 UTC

    Also note that it is possible to declare a lexical inside the parentheses of the "if with a block" which leads to an interesting variation of the scope theme:

    use strict; use warnings; my @L = ('1', '0', ''); while (@L) { if (my $x = shift @L) { print "\$x is true: <$x>\n"; } elsif (length $x) { print "\$x is false: <$x>\n"; } else { print "\$x is still false<$x>\n"; } # print "$x\n"; # yields a strict error when uncommented }

    Which prints:

    $x is true: <1> $x is false: <0> $x is still false<>

    You see that the scope of that lexical is all the way down to the closing curly of the last appendant else-block.

    Though it seems the declaration of $x is outside of the if-elsif-else-blocks, its scope actually is only the (complete) conditional.
    Uncommenting the print statement outside the conditional yields the "strict vars" error again.

Re: difference between 'if (condition) { expression;}' and 'expression if (condition)'
by timos (Beadle) on Mar 22, 2006 at 14:33 UTC
    This is easy: The two bracets make up an extra namespace, in which $var is "declared" in the first examples. But the print statement is out of that namespace, so $var is not known there.
      The two bracets make up an extra namespace

      I would avoid calling this a "namespace". The brackets in this example are creating a lexical scope. When someone says "namespace" in Perl, they almost always mean a package.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://538512]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2023-09-26 19:28 GMT
Find Nodes?
    Voting Booth?

    No recent polls found