Reputation: 960
I am trying to understand an example of code given here: https://www.perlmonks.org/?node_id=1083257 and the difference between the directly created hash references given in the example and one that I alternatively create first as a hash. When I run the following code:
use strict;
use warnings;
use Algorithm::NaiveBayes;
my $positive = {
remit => 2,
due => 4,
within => 1,
};
my $negative = {
assigned => 3,
secured => 1,
};
my $categorizer = Algorithm::NaiveBayes->new;
$categorizer->add_instance(
attributes => $positive,
label => 'positive');
$categorizer->add_instance(
attributes => $negative,
label => 'negative');
$categorizer->train;
my $sentence1 = {
due => 2,
remit => 1,
};
my $probability = $categorizer->predict(attributes => $sentence1);
print "Probability positive: $probability->{'positive'}\n";
print "Probability negative: $probability->{'negative'}\n";
I get the result:
Probability positive: 0.999500937781821
Probability negative: 0.0315891654410057
However, when I try to create the hash reference in the following way:
my %sentence1 = {
"due", 2,
"remit", 1
};
my $probability = $categorizer->predict(attributes => \%sentence1);
I get:
Reference found where even-sized list expected at simple_NaiveBayes.pl line 57.
Probability positive: 0.707106781186547
Probability negative: 0.707106781186547
Why is my hash \%sentence1
different from the $sentence1
hash reference given in the example?
Upvotes: 1
Views: 86
Reputation: 67910
Just like the warning says, you are assigning a reference where an even-sized list was expected. This
my %sentence1 = { # curly bracers create a hash reference, a scalar value
"due", 2,
"remit", 1
};
Should look like this
my %sentence1 = ( # parentheses used to return a list (*)
"due", 2,
"remit", 1
);
(*): Parentheses do not actually create a list, they just override precedence. In this case of =
over ,
or =>
, which returns a list of items to the assignment.
Or this
my $sentence1 = { # scalar variable is fine for a reference
"due", 2,
"remit", 1
};
If you want to get technical, what is happening in your hash assignment is that the hash reference { ... }
is stringified and turned into a hash key. (The string will be something like HASH(0x104a7d0)
) The value of that hash key will be undef
, because the "list" you assigned to the hash only contained 1 thing: The hash reference. (Hence the "even-sized list" warning) So if you print such a hash with Data::Dumper
, you would get something that looks like this:
$VAR1 = {
'HASH(0x104a7d0)' => undef
};
Upvotes: 4
Reputation: 240521
my %sentence1 = {
"due", 2,
"remit", 1
};
You did this wrong (you tried to create a hash with one key, which is a hashref (which doesn't work) and no corresponding value). That's why perl gave you a warning about finding a reference instead of an even-sized list. You wanted
my %sentence1 = (
"due", 2,
"remit", 1
);
Upvotes: 4