Reputation: 79
I use below Perl code, and want to add specific $i
in foreach into variable $targetBank
and $targetEntry
.
For 1_Target Bank & 1_Target Entry they are ok to print out.
But for 2_Target Bank & 2_Target Entry they are not working.
It seems the $targetBank
and $targetEntry
variable refresh every time in the foreach loop.
How should I modify my code?
my @SPLIT =split /\./, $longSentense;
foreach my $i (@SPLIT)
{
if($i =~ /u_b.*/)
{
my $targetBank=$i;
print "1_Target Bank= $targetBank\n";
}
elsif ($i =~ /g_tq.*/)
{
my $targetEntry=$i;
print "1_Target Entry= $targetEntry\n";
}
}
print "2_Target Bank= $targetBank\n";
print "2_Target Entry= $targetEntry\n";
Upvotes: 0
Views: 86
Reputation: 6626
First, always add use strict; use warnings;
at the beginning of your scripts (more or that later).
A variable is only visible in the scope it was defined in. For instance, if you do:
{
my $var = 42;
print "1: $var\n"; # prints "1: 42"
}
print "2: $var\n"; # ERROR !!!
$var
is visible inside the { ... }
block, but not after. With use strict
, the print "2: $var\n";
will not compile, because $var
is not declared in this scope. Without use strict
, this statement will work, but $var
will be undefined.
To get this example to work, you need to declare $var
in the same scope as print "2: $var\n"
:
my $var;
{
$var = 42;
print "1: $var\n"; # prints "1: 42"
}
print "2: $var\n"; # prints "2: 42", as expected.
Note how I wrote $var = 42
rather than my $var = 42
: the later would declare a new variable (in this scope only), which would "shadow" the previous declaration, and, when exiting the scope (at }
), the $var
that would be visible would be the one declare before the block, which would still be undefined.
Also, the word "scope" is maybe a bit confusing. You can (mostly) think of a scope as "everything inside curly braces + the global scope": if () { new scope here }
, for (...) { new scope here }
, sub { new scope here }
, and, everything that is not inside a block is in the global scope. Small subtlety: when you write if (my $var = ...) { ... }
or for my $var (...) { ... }
, it introduces 2 scopes: one with $var
, and one inside the { ... }
(and they are both closed at the end of the if/for). See this small tutorial about scopes.
Thus, your code should be:
use strict; # never omit
use warnings; # those 2 lines
my @SPLIT =split /\./, $longSentense;
my ($targetBank, $targetEntry); # Declaring your variables
foreach my $i (@SPLIT)
{
if($i =~ /u_b/)
{
$targetBank=$i;
print "1_Target Bank= $targetBank\n";
}
elsif ($i =~ /g_tq/)
{
$targetEntry=$i;
print "1_Target Entry= $targetEntry\n";
}
}
print "2_Target Bank= $targetBank\n";
print "2_Target Entry= $targetEntry\n";
Note that each time $targetBank=$i;
is executed, the previous value of $targetBank
is lost. If the condition if($i =~ /u_b/)
is true only once in your loop, then this is not an issue. Otherwise, you might want to use an array instead of a scalar to store multiple values.
Also, as pointed out by @TLP, /u_b.*/
and /g_tq.*/
can be simplified to /u_b/
and /g_tq/
.
Upvotes: 1