Reputation: 377
I've got an array of hashes:
my @questions = (
{"Why do you study here?" => "bla"},
{"What are your hobbies?" => "blabla"});
And I try to loop through it:
foreach (@questions) {
my $key = (keys $_)[0];
$content .= "\\section{$key}\n\n$_{$key}\n\n";
}
giving me
Use of uninitialized value in concatenation (.) or string at convert.pl line 44.
Where does the error come from?
Upvotes: 5
Views: 147
Reputation: 24063
Gilles already explained how to use your current data structure, but I would recommend that you use a different data structure altogether: a simple hash.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my %answers = (
"Why do you study here?" => "bla",
"What are your hobbies?" => "blabla"
);
while (my ($question, $answer) = each %answers) {
say "Question: $question";
say "Answer: $answer";
}
Question: Why do you study here?
Answer: bla
Question: What are your hobbies?
Answer: blabla
I find this easier to work with than an array of hashes, each of which only contains a single key/value pair.
If you want to iterate through the hash in a certain (non-sorted) order, there are a couple of options. The simplistic solution is to maintain an array of keys in the order you want to access them:
# In the order you want to access them
my @questions = ("What are your hobbies?", "Why do you study here?");
my %answers;
@answers{@questions} = ("blabla", "bla");
foreach my $question (@questions) {
say "Question: $question";
say "Answer: $answers{$question}";
}
Question: What are your hobbies?
Answer: blabla
Question: Why do you study here?
Answer: bla
Another option is to use Tie::IxHash (or the faster XS module Tie::Hash::Indexed) to access keys in insertion order:
use Tie::IxHash;
tie my %answers, "Tie::IxHash";
%answers = (
"Why do you study here?" => "bla",
"What are your hobbies?" => "blabla"
);
while (my ($question, $answer) = each %answers) {
say "Question: $question";
say "Answer: $answer";
}
Question: Why do you study here?
Answer: bla
Question: What are your hobbies?
Answer: blabla
Upvotes: 2
Reputation: 15121
The elements of @questions
are references to hash, not hashes. Therefore, you should use them like this:
foreach (@questions) {
my $key = (keys %$_)[0];
print "\\section{$key}\n\n$_->{$key}\n\n";
}
See perlref for how to create and use reference.
Upvotes: 2
Reputation: 107759
$_{$key}
looks up $key
in the hash variable %_
. The sigil $
at the beginning indicates that the type of the result is a scalar. It's the syntactic construct VAR{KEY}
that determines that VAR
must be a hash. Although $_
and %_
use the same symbol as a name, the different sigils make them unrelated variables.
You need to dereference the hash reference $_
into the underlying hash. The syntax for this is $_->{$key}
or ${$_}{$key}
.
See the reference tutorial for a more general presentation of the topic.
Upvotes: 3