Я пытаюсь понять приведенный здесь пример кода: https://www.perlmonks.org/?node_id=1083257 и разницу между непосредственно созданными хеш-ссылками, приведенными в примере, и той, которую я альтернативно создаю сначала как хэш. Когда я запускаю следующий код:
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";
Я получаю результат:
Probability positive: 0.999500937781821
Probability negative: 0.0315891654410057
Однако, когда я пытаюсь создать ссылку на хеш следующим образом:
my %sentence1 = {
"due", 2,
"remit", 1
};
my $probability = $categorizer->predict(attributes => \%sentence1);
Я получил:
Reference found where even-sized list expected at simple_NaiveBayes.pl line 57.
Probability positive: 0.707106781186547
Probability negative: 0.707106781186547
Почему мой хэш \%sentence1
отличается от ссылки на хэш $sentence1
, приведенной в примере?
my %sentence1 = {
"due", 2,
"remit", 1
};
Вы сделали это неправильно (вы пытались создать хэш с одним ключом, который является хэш-ссылкой (который не работает) и не имеет соответствующего значения). Вот почему perl выдает предупреждение о поиске ссылки вместо списка четного размера. Вы хотели
my %sentence1 = (
"due", 2,
"remit", 1
);
Как говорится в предупреждении, вы назначаете ссылку там, где ожидался список четного размера. Этот
my %sentence1 = { # curly bracers create a hash reference, a scalar value
"due", 2,
"remit", 1
};
Должно выглядеть так
my %sentence1 = ( # parentheses used to return a list (*)
"due", 2,
"remit", 1
);
(*): Скобки на самом деле не создают список, они просто переопределяют приоритет. В данном случае =
над ,
или =>
, что возвращает список элементов в задание.
Или это
my $sentence1 = { # scalar variable is fine for a reference
"due", 2,
"remit", 1
};
Если вы хотите получить техническую информацию, то в вашем назначении хэша происходит то, что ссылка на хэш { ... }
преобразуется в строку и превращается в хеш-ключ. (Строка будет выглядеть примерно так: HASH(0x104a7d0)
) Значение этого хеш-ключа будет undef
, потому что «список», который вы назначили хешу, содержал только 1 вещь: ссылку на хеш. (Отсюда и предупреждение о «списке четного размера»). Итак, если вы напечатаете такой хэш с помощью Data::Dumper
, вы получите что-то вроде этого:
$VAR1 = {
'HASH(0x104a7d0)' => undef
};
@ikegami Технически это верно, но сложно выразиться кратко. Я добавил объяснение.
«Просто назначьте список непосредственно хэшу. Вам понадобятся скобки из-за неудачного приоритета операторов».
Относительно «скобки создают список», скобки никогда не создают список. Скобки используются для перезаписи приоритета. (Было бы
( my %sentence1 = "due" ), 2
без скобок.)