Странности модуля Crypt::GeneratePassword

13.06.2013г. // Рубрики: Рецепты, Perl
Вкратце, ситуация такая - есть конструкция
package Bla-bla-bla;
use Crypt::GeneratePassword qw(chars);
sub new {
     ......
}
sub method {
     ......
     my $var = chars(32,32, [chr(48)..chr(57), chr(65)..chr(90), chr(97)..chr(122)]);
     ......
}
На выходе в $var - случайная буквенная последовательность длиной 32 символа из определенных диапазонов. Новый вызов - новая случайная последовательность. Всё просто. В теории.
На практике, это дело крутится под mod_perl 2, а сам модуль вызывается из плагина Template-Toolkit 2. Мне вот так трудно сказать, чья именно вина в цепочке, но в определенных ситуациях оказалось, что в $var в двух вызовах подряд оказывалась одинаковая строка.
Ситуация была воспроизводима, но при первой же попытке поймать баг в отладчике - тут же модуль стал работать правильно, честно выдавая различные значения. А вот если строчку обложить принтами - видно, что функция chars вызывается и дважды выдает одно и тоже. Если бы ещё и print не сработал - я бы подумал, что тут квантомеханические эффекты проявляются, а так вроде мистика всего лишь половинчатая.
Почитал документацию к модулю на CPAN, почесал репу, грустно вздохнул и от безысходности добавил srand перед chars, и - чудо! Глюк моментально пропал.
До истины уже не стал докапываться - и так угробил на отлов бага вторую половину праздничного дня (дня независимости России от Средней Азии, Украины и Прибалтики вместе взятых - если кто не в курсе). Сам по себе Crypt::GeneratePassword очень уж удобен, поэтому  уже вечером прошерстил все свои коды и всюду вставлял srand перед вызовом chars.
Итак, работоспособный вариант
package Bla-bla-bla;
use Crypt::GeneratePassword qw(chars);
sub new {
     ......
}
sub method {
    ......
    srand;
    my $var = chars(32,32, [chr(48)..chr(57), chr(65)..chr(90), chr(97)..chr(122)]);
    ......
}

Рубрики