'Perl: Create a hash file using a loop
I import data from an XML-file and want to output the content into a log-file. Doing this I created for each entity a scalar (2). To output the entities with a loop I created a hash (3 and 4b) and with the for loop I output the name of the tag (entity) and the value (5). To get a specified order I use Tie::IxHash. Now, I wonder if I could avoid steps (3) and (4b) using a for loop. For example I could put the scalars $x1,$x2 and $x3 in an array and doing the steps (3) and (4b) with a loop. Is it possible?
use strict;
use warnings;
use Data::Dumper;
use Tie::IxHash;
my $x1 = 'a';
my $x2 = '';
my $x3 = undef; # no xml tag <x3>;
# (3) Create a hash to output values in a log files using for
my $rx1 = \$x1;
my $rx2 = \$x2;
my $rx3 = \$x3;
# (4a) To make an ordered hash use Tie::IxHash
my %h;
tie %h, 'Tie::IxHash';
%h = ( 'x1' => $rx1
, 'x2' => $rx2
, 'x3' => $rx3);
# (4c) Output hash with undex content gives a warning
print map { "$_ ${$h{$_}}\n" } keys %h; # 51
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
print "--------\n";
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined ${$h{$k}} or ${$h{$k}} eq "" ) {${ $h{$k}} = undef; }
if ( defined ${$h{$k}} ) { print "$k : ${$h{$k}} \n"; } else {print "$k : undef\n"; }
}
This gives the output:
# Output:
# Use of uninitialized value in concatenation (.) or string at test.pl line 51.
# x1 a
# x2
# x3
# --------
# using keys from hash:
# x1 : a
# x2 : undef
# x3 : undef
Update 1:
Thanks to Dave Cross I came up with this. It works for me.
# Define hash [(step (1)-(4)]
%h = ( 'x1' => my $x1
, 'x2' => my $x2
, 'x3' => my $x3
);
# import from xml
$h{x1} = 'a';
$h{x2} = '';
$h{x3} = undef;
# (5) Output content of hash into a log file
print "using keys from hash:\n";
foreach my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
Update 2
I simplified thanks to suggestions of choroba and Dave Cross. Now it is short and organized. I learned that you can assign data from interfaces directly into scalars which are within a hash or an array. Usually I like to declare scalar variables separatly but in this, if you have a myriad of variables it makes sense to write it only once into a hash or array and to declare the hash or array separatly.
# Define hash [(step (1)-(4)]
%h = ( x1 => $xpc->findvalue('./X1',$node1)
, x2 => $xpc->findvalue('./X2',$node1)
, x3 => $xpc->findvalue('./X3',$node1)
);
# (5) Output content of hash into a log file
print "using keys from hash:\n";
for my $k (keys %h) {
if ( not defined $h{$k} or $h{$k} eq "" ) { $h{$k} = undef; }
if ( defined $h{$k} ) { print "$k : $h{$k} \n"; } else {print "$k : undef\n"; }
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
