Подтвердить что ты не робот

Что вы получаете, если оцениваете хэш в скалярном контексте?

Рассмотрим следующий фрагмент:

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 'кортежей'?

Спасибо всем за ваши ответы до сих пор:)

4b9b3361

Ответ 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 [...]