Пытаясь понять, как работает решение 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).
На первый взгляд, похоже, что установка @_
имеет к этому какое-то отношение, но я не уверен. Может ли кто-нибудь пролить свет на то, что здесь происходит?
Я думал, что на этот вопрос был дан ответ, пока refp не предоставил обновление. Почему форма arrayref не страдает от той же проблемы, о которой говорилось выше? :
[@_=%hash]->[1|rand@_] for 1 .. 10; # First value is random