the perl code is like followed : the problem is that I can not read $key inside sub tweak_server{} ….
my $key;
my %hash = ( flintstones => [ "C:/Users1/f1.xml", "C:/Users1/f2.xml" ],
jetsons => [ "C:/Users2/f1.xml" ],
simpsons => [ "C:/Users3/f1.xml", "C:/Users3/f1.xml", "C:/Users3/f1.xml" ], );
foreach $key (keys%hash){
if (scalar@{$hash{$key}}>1){
foreach my $path (@{$hash{$key}}){
my $filehandle;
open($filehandle, "+<$path") or die "cannot open out file out_file:$!";
my $roots = { TAG => 1 };
my $handlers = { 'ROOT/TAG' => \&tweak_server,
};
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers,
twig_print_outside_roots => \*$filehandle);
$twig->parsefile($path);
say $key;#could read key
sub tweak_server {
my ($twig, $root) = @_;
my $tag2=$root->first_child_text('TAG2');
say $key;# could not read
if ($tag2=~/$key/){
#BLABLA
}
$twig->flush( $filehandle, pretty_print => 'indented');
}
}
}
}
as i state, the $key can be read outside the sub, but not inside..the error appeared:Use of uninitialized value $key
and then i tried a simple situation, just like
my $a="aaa";
open( $filehandle, "+<$path") or die "cannot open out file out_file:$!";
my $roots = { TAG => 1 };
my $handlers = { 'ROOT/TAG' => \&tweak_server,
};
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers,
twig_print_outside_roots => \*$filehandle
);
$twig->parsefile($path);
sub tweak_server {
say $a;
my ($twig, $root) = @_;
my $tags=$root->first_child_text('TAG2');
my $str="204B";
if ($tag2=~m/$str/){
foreach my $b(1...6){
say $a; }
}
$twig->flush( $filehandle, pretty_print => 'indented');
}
in this code, the $a can be read….
i spent one day on this, but still can’t fix it…crazy now
thank in advance!!
You are declaring
$keyoutside of theforloop. Then, inside the for loop, you define a subroutine that closes on$key.As a general rule, declare variables in the smallest applicable scope. For example:
or
Why are you defining
sub tweak_serverin the body of theforloop? It seems to me, what you want to do is to define a new anonymous sub for each iterationn.First, a short example that replicates what you are observing:
Now, the fix:
This way, we define a new anonymous function at each iteration and each new sub closes over each value of the loop variable.
In terms of your code, you should then replace the named sub with
Or, even better, as @mirod observes, pass
$keytotweak_server:And, in the body of the loop,