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

How do I get the variable $lookfor to be available outside the if statement?   And/or what is a better way to do this?   Minus all the spacing issues.

use strict; if ($line =~ /TC/g) { my $lookfor = "TC"; } else { my $lookfor = "26 "; } print $lookfor;

janitored by ybiC: Balanced <code> tags around codeblock, wee tiny format cleanups, strike extraneous leading "use strict; " from title

Replies are listed 'Best First'.
Re: Use variable outside if statement
by davido (Cardinal) on Dec 17, 2003 at 22:52 UTC
    You have to create $lookfor at a broader scope. The {...} brackets effectively limit the variable's scope. Here is how you would make it available outside of the {...} block:

    use strict; my $lookfor; if ( $line =~ /TC/g ) { $lookfor = "TC"; } else { $lookfor = "26"; }

    Update: Or you could use a different Perl idiom:

    use strict; my $lookfor = ( $line =~ /TC/g ) ? "TC" : "26";

    Note, in the snippet you provided, the /g modifier on your RE isn't doing anything for you.


    Dave

Re: Use variable outside if statement
by pg (Canon) on Dec 18, 2003 at 04:05 UTC

    If the code is also used at other places, then put in a sub:

    use strict; print foo("abcCj"); sub foo { return ($_[0] =~ /TC/g) ? "TC" : "26 "; }

    The points here are:

    • First, the ultimate way to set the right scope for your variables is to modulize your code, fully utilize things like package, class, sub etc.
    • Always define your variables in the smallest scope that can yet be accessed by all parts that need it
      That's a very good point. And in situations where a seperate sub may be inconvenient, an enclosing lexical block can be helpful:

      use strict; use warnings; my $var = 10; { my $var = 20; print $var, "\n"; } print $var, "\n"; __OUTPUT__ 20 10

      ...just a quick demonstration of using {...} blocks to limit scope and protect variables of broader scope.

      Perl is great at providing mechanisms for lexical scoping: file-based scope, package scope, block scope, subroutine scope, as well as other mechanisms such as do{...}; and eval. It can be a tricky maze to wander at first, but definately flexible.

      Perl programmers are lucky in that they can decide just how complex or simple they want their scoping and modularization to be.


      Dave

        That depends on whether you are the guru, able to exploit a rich syntax to create compact and elegant code, or a novice struggling to comprehend what may look like line noise to you. Perl's expressivity as a language can be a wonderful thing, but it comes as a dangerous double edged sword. What is and is not appropriate to write depends on your target audience. Reckless and excessive use of some of Perl's more arcane functionality is what often gets Perl branded as a write only language amongst the unenlightened, and also causes Perl to lean toward unmanageability when code bases grow large.
Re: Use variable outside if statement (use ? : or do {...})
by grinder (Bishop) on Dec 18, 2003 at 09:01 UTC

    At the simplest, you can use the ternary ? : operator to achieve this:

    my $lookfor = ($line =~ /TC/g) ? 'TC' : 26; print $lookfor;

    This works when the expression is simple. When things start to get complicated, the operator tends to get lost in the rest of the code and it takes more time to decipher the meaning. In cases like these I'm fond of using the do statement:

    my $lookfor = do { if( $line =~ /^(\w{3})(\d{3})/ ) { my ($token, $repeat) = ($1, $2); $token x $repeat; } else { lc( substr( $line, 0, 4 )); } };

    The beauty of this approach is that it reduces the scope of intermediate variables. In the above (contrived) example, the variables $token and $repeat are not visible outside the do block. This is a Good Thing.

    The only gotcha to look out for is to remember the trailing semicolon on the do.

Re: Use variable outside if statement
by ysth (Canon) on Dec 18, 2003 at 21:35 UTC
    How do I get the variable $lookfor to be available outside the if statement?
    In the spirit of answering the question and not questioning it, and only because others have already said what should be said, see Rebinding closures by scope and do:
    use strict; use ScopeSaver; my $scopeobj; my $line = "A TC B"; if ($line =~ /TC/g) { my $lookfor = "TC"; $scopeobj = eval ScopeSaver->new(lexical=>['$lookfor']); } else { my $lookfor = "26 "; $scopeobj = eval ScopeSaver->new(lexical=>['$lookfor']); } $scopeobj->scope_eval('print $lookfor');
A reply falls below the community's threshold of quality. You may see it by logging in.