Reference found where even-sized list expected

I started working myself though a long list of unfixed warnings today and encountered something I didn't see before: Reference found where even-sized list expected at project/ The message seems to be clear, but do you find the problem at line 573?

565 if (!$question_ids) {
566 $dbg->out("getting...");
567 $question_ids = get_question_ids(
568 dbh => $dbh,
569 dbg => $dbg,
570 group_ids => $group_ids,
571 );
572 }
574 return if (($data_href->{'demo_mode'} || $q_type == 1 || $q_type == 42) && !$question_ids);
576 my %questions = $question_ids ? map {$_ => 1} split(",", $question_ids) : {};

Perl Camel auf der YAPC::EU 2012It took me some minutes until I discovered the problem. It's - obviously - not on line 573 as reported and not the statement starting on line 567. The warning is hiding at line 576:

If $question_ids is true, it's contents are used as the keys for the new hash, but if no questions are found, a HashRef is being used as default value.

Remember: References are not allowed as hash keys. They're converted to plain text and no longer usable as a reference:

#!/usr/bin/perl -l
use Data::Dumper;
%X = (a => 1);
print "Original: ".Dumper(\%X);
%Y = (\%X => \%X);
print "keys: ".(keys(%Y))[0];
print "values: ".(values(%Y))[0];
print Dumper(keys %Y);
print Dumper(values %Y);

%X is the sample hash. It's reference is being used both as the key and value for a %Y item. The script's output shows the difference between both:

Original: $VAR1 = {
'a' => 1
keys: HASH(0x14b7720)
values: HASH(0x14b7720)
$VAR1 = 'HASH(0x14b7720)';
$VAR1 = {
'a' => 1

The key is always plain text HASH(0x14b7720), but the value is still a valid reference.

Back to the original message: Using an empty list instead of a anonymous hashref solves the warning and avoid unexpected results lateron:

576 my %questions = $question_ids ? map {$_ => 1} split(",", $question_ids) : ();

With {}, %questions would end up with a single key (the plain text representation of the anonymous hashref) having a undef value - which is usually not what you want.


2 Kommentare. Schreib was dazu

  1. Kim R. T. Hansen

    Did you find out why the line numbers in the error message was wrong?

    • Sebastian

      Sorry, no.
      But it's always wise to check the surrounding lines if an error message doesn't make sense for a line or just make the reported line a comment and check if the error is gone.

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>