Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl variable scoping and using the same variables in an if/else block

Tags:

perl

I am trying to figure out how I can use the same variables in my if/else blocks. For example,

$var1
$var2
$var3

if(condition) {
...
}
else {
...
}

I need to access $vars1, 2, and 3 in the blocks, but I cannot. I think I have a scoping issue. I tried making them global, but I see many errors and the program doesn't run properly. What am I missing?

Here is my code. My issue is that the variables at the bottom(@varList, etc) are needed for the server because this is a script on an apache server that also uses CGI. it spits out errors like this:

[error] Global symbol "$questionslist" requires explicit package name at /home/megaoff/www/vi
ewquestions.dhtml line 46.\nGlobal symbol "$site" requires explicit package name at /home/megaoff/www/viewquestions.dhtm
l line 46.\nGlobal symbol "$xs" requires explicit package name at /home/megaoff/www/viewquestions.dhtml line 46.\nGlobal
 symbol "$username" requires explicit package name at /home/megaoff/www/viewquestions.dhtml line 46.\n

#!/usr/bin/perl

use strict;
use CGI;
use BarryP;

my $pagev = BarryP::makeP("noextracook", 1);
my $bvga = $pagev->{'vga'};
my %vga = %$bvga;
my $cgi = CGI->new;
my $usePage = "answerquestions.html";
my $anslist = "/home/megaoff/www/limages/anslist.txt";
my $unanslist = "/home/megaoff/www/limages/unanslist.txt";

my $action = $vga{"action"};


if($action eq 'adminmode') {
    my @a_list = $pagev->listFile($anslist);
    my %list = map { split(/\t/, $_, 2) } @a_list;
}   
else {
    my @u_list = $pagev->listFile($unanslist);
    chomp @u_list;
    my %questions = map { $_ => '' } @u_list;
    my $question = $cgi->param('question');
    my $answer = $cgi->param('answer');
    chomp($question, $answer);

    open(my $ANS, '>>', $anslist) or die "Can't open file $anslist: $!";
    print $ANS "$question\t$answer\n";
    close($ANS) or die "Can't close file $anslist: $!";

    delete $questions{$question};
    open(my $UNANS, '>', $unanslist) or die "Can't open file $unanslist: $!";
    print $UNANS "$_\n" foreach keys %questions;
    close($UNANS) or die "Can't close file $unanslist: $!";

    my $questionslist = join("<br>", @u_list);
    my $site = $pagev->{'site'};
    my $xs = $pagev->{'xs'};
    my $username = $pagev->{'username'};
}

my @varList = ('questionslist', $questionslist, 'action', $action, 'site', $site, 'xs', $xs, '$username', $username);

$pagev->pageHeader($usePage, @varList);
like image 954
Jonathan Dewein Avatar asked Jul 03 '13 20:07

Jonathan Dewein


2 Answers

Your issue is with scoping. On line 46 when you're referencing $questionlist et al, they've already fallen out of scope because you defined them in the else block.

You have (simplified):

if ($blah) {
  # do stuff
} else {
  # do other stuff
  my $variable = "something";
}

doSomethingWith($variable); # illegal, $variable is not in scope.

$variable isn't defined outside of the else block, and the else block might not even be executed. You either need to put the function in the else block, or find some way to give those variables default values, and declare them before the if statement.

like image 158
OmnipotentEntity Avatar answered Sep 23 '22 20:09

OmnipotentEntity


Ideally, your variable declarations should have the tightest scope possible while still being in scope of the code that need to access the variables.

my $var1 = 'aBcD';
my $var2;
if ($uc) {
   $var2 = uc($var1);
}
else {
   $var2 = lc($var1);
}

Of course, that could be written

my $var1 = 'aBcD';
my $var2 = $uc ? uc($var1) : lc($var1);
like image 38
ikegami Avatar answered Sep 24 '22 20:09

ikegami