Почему этот селектор случайных хэш-значений всегда возвращает одно и то же значение при первом вызове?

Пытаясь понять, как работает решение refp для выбора случайного хэш-значения, я заметил кое-что странное.

При повторных вызовах следующего Perl-скрипта я постоянно обнаруживал, что первый возвращаемый результат был одним и тем же. Последующие возвращаемые значения были случайными:

use strict;
use warnings;
use 5.010;

my %hash = map { $_ => ord $_ } 'a' .. 'z';

say( (@_=%hash)[1|rand@_] ) for 1 .. 10;       # First value always 119

Интересно, что следующий вариант не страдает от этой проблемы:

sub random_value { ( @_ )[ 1 | rand @_ ] }

say random_value %hash for 1 .. 10;            # First value is random

Удаление ссылок на @_ также устраняет проблему:

say( (%hash)[1|rand keys %hash] ) for 1 .. 10; # First value is random

Это было проверено на Windows (ActivePerl 5.14.2).

На первый взгляд, похоже, что установка @_ имеет к этому какое-то отношение, но я не уверен. Может ли кто-нибудь пролить свет на то, что здесь происходит?


EDIT

Я думал, что на этот вопрос был дан ответ, пока refp не предоставил обновление. Почему форма arrayref не страдает от той же проблемы, о которой говорилось выше? :

[@_=%hash]->[1|rand@_] for 1 .. 10;            # First value is random

7
задан Community 23 May 2017 в 10:34
поделиться