Что вы получите, если оцените хеш в скалярном контексте? - PullRequest
22 голосов
/ 15 сентября 2011

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

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-хеш в скалярном контексте?

Редактировать

Я добавил несколько других хешей для печати:

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

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

Ответы [ 4 ]

23 голосов
/ 15 сентября 2011

Хеш - это массив связанных списков. Функция хеширования преобразует ключ в число, которое используется в качестве индекса элемента массива («корзины»), в который сохраняется значение. Связанный список обрабатывает случай, когда более одного ключа хеширует один и тот же индекс («столкновение»).

Знаменателем дроби является общее количество ведер.

Числитель дроби - это количество сегментов, содержащих один или несколько элементов.

Для хэшей с одинаковым количеством элементов, чем больше число, тем лучше. Тот, который возвращает 6/8, имеет меньше коллизий, чем тот, который возвращает 4 / 8.

8 голосов
/ 15 сентября 2011

С perldoc perldata:

Если вы оцениваете хеш в скалярном контексте, он возвращает false, если хеш пустой. Если есть какие-либо пары ключ / значение, возвращается true; Больше точно, возвращаемое значение является строкой, состоящей из числа использованные сегменты и количество выделенных сегментов, разделенных слэш.

В вашем случае у вас есть пять значений (1, 2, ''cucu', undef и '321312321'), которые сопоставлены восьми клавишам (a, b, c, d, r, br, cr и dr).

2 голосов
/ 15 сентября 2011

Количество используемых блоков начинается примерно с количества ключей; Выделенные сегменты - это наименьшая степень 2> количества ключей. 5 ключей вернутся 5/8. Большее число уникальных ключей растет медленнее, так что хеш% h, который является просто списком (1..128), с 64 парами ключ / значение, каким-то образом получает скалярное значение 50 / 128.

Однако, как только хэш выделит свои сегменты, они останутся распределенными, даже если вы уменьшите хэш. Я только что сделал хеш% h с 9 парами, таким образом, 9/16 скаляр; затем, когда я переназначил% h на одну пару, его скалярное значение было 1 / 16.

Это на самом деле имеет смысл, поскольку позволяет вам проверять размер хеша, как это делает скаляр простого массива.

1 голос
/ 21 марта 2017

Если слишком сосредоточиться на этом дробном паттерне (в качестве индикатора для внутренних деталей хэша), это может сбить с толку. Существует аспект «скалярного значения» хэша, который важен потенциально для каждой Perl-программы, а именно, если он считается true в логический контекст см. пример:

if (%h) {
    print "Entries in hash:\n";
    for my $k (sort keys %h) {
        print "$k: $h{$k}\n";
    }
}

В perldoc perldata , раздел Скалярные значения , вы можете прочитать, что

[...] Логический контекст - это просто особый вид скалярного контекста, в котором преобразование в строку или число никогда не выполняется.

и несколько абзацев позже

Если вы оцениваете хеш в скалярном контексте, он возвращает false, если хеш пустой. Если есть какие-либо пары ключ / значение, возвращается true [...]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...