Что вы получаете, если оцениваете хэш в скалярном контексте?
Рассмотрим следующий фрагмент:
use strict;
use warnings;
my %a = ( a => 1,
b => 2,
c => 'cucu',
d => undef,
r => 1,
br => 2,
cr => 'cucu',
dr => '321312321',
);
my $c = %a;
print $c;
Результат этого 5/8
, и я не понимаю, что это представляет. Я где-то читал, что число из этого результата, представляющего фракцию, может представлять количество ведер из хеша, но, очевидно, это не так.
Кто-нибудь знает, как оценивается хеш perl в скалярном контексте?
Edit
Я добавил несколько других хэшей для печати:
use strict;
use warnings;
use 5.010;
my %a = ( a => 1,
b => 2,
c => 'cucu',
d => undef,
r => 1,
br => 2,
cr => 'cucu',
dr => '321312321',
);
my $c = %a;
say $c; # 5/8
%a = ( a => 1,
b => 21,
c => 'cucu',
br => 2,
cr => 'cucu',
dr => '321312321',
);
$c = %a;
say $c; # 4/8
%a = ( a => 1,
b => 2,
c => 'cucu',
d => undef,
r => 1,
br => 2,
cr => 'cucu',
dr => '321312321',
drr => '32131232122',
);
$c = %a;
say $c; #6/8
Итак, вы называете "кортеж" похожим на a => 1
ведро в хеше? в этом случае, почему последний хэш все еще имеет 8 в качестве знаменателя, когда он имеет 9 'кортежей'?
Спасибо всем за ваши ответы до сих пор:)
Ответы
Ответ 1
Хеш - это массив связанных списков. Функция хэширования преобразует ключ в число, которое используется как индекс элемента массива ( "ведро" ), в который будет храниться значение. Связанный список обрабатывает случай, когда более одного хэша ключа имеет один и тот же индекс ( "столкновение" ).
Знаменатель дроби - это общее количество ведер.
Числитель дроби - это количество ведер, имеющих один или несколько элементов.
Для хэшей с одинаковым количеством элементов, чем больше число, тем лучше. Тот, который возвращает 6/8, имеет меньше коллизий, чем тот, который возвращает 4/8.
Ответ 2
От perldoc perldata
:
Если вы оцениваете хэш в скалярном контексте, он возвращает false, если хэш пусто. Если есть пары ключ/значение, он возвращает true; Больше точно, возвращаемое значение представляет собой строку, состоящую из числа использованные ковши и количество выделенных ведер, разделенных слэш.
В вашем случае у вас есть пять значений (1
, 2
, ''cucu'
, undef
и '321312321'
), на которые были отображены восемь клавиш (a
, b
, c
, d
, r
, br
, cr
и dr
).
Ответ 3
Количество используемых ведер начинается примерно с количества клавиш; выделенные ведра, как правило, являются наименьшей мощностью 2 > количества ключей. 5 клавиш вернут 5/8. Большее количество уникальных ключей растет медленнее, так что хеш% h, который является только списком (1..128), с 64 парами ключ/значение, каким-то образом получает скалярное значение 50/128.
Однако, как только хэш выделит свои ведра, они останутся выделенными, даже если вы уменьшите хэш. Я просто сделал хэш% h с 9 парами, таким образом 9/16 скаляр; тогда, когда я переназначил% h, чтобы иметь только одну пару, его скалярное значение было 1/16.
Это на самом деле имеет смысл в том смысле, что позволяет проверить размер хэша, например, скаляр простого массива.
Ответ 4
Чтобы слишком сильно сфокусироваться на этом дробном шаблоне (в качестве индикатора внутренних деталей хэша), вы можете ввести в заблуждение. Существует один аспект "скалярного значения" хэша, который важен для потенциально каждой программы Perl, и если это считается истиной в булевом контексте, см. пример:
if (%h) {
print "Entries in hash:\n";
for my $k (sort keys %h) {
print "$k: $h{$k}\n";
}
}
В perldoc perldata, раздел Scalar-values , вы можете прочитать, что
[...] Логический контекст - это просто особый вид скалярного контекста, в котором никогда не выполняется преобразование в строку или число.
и, несколько абзацев позже,
Если вы оцениваете хэш в скалярном контексте, он возвращает false, если хэш пусто. Если есть пары ключей/значений, он возвращает true [...]