Все задачи

Сравнение массивов

07 Oct 2013

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

Если отбросить несущественные детали, код получился такой:

my @array1 = qw(11 22 33);
my @array2 = ('11', "22", 33);
if ( join '*', @array1 eq join '*', @array2 ) {
    print '@array1 eq @array2';
} else {
    print '@array1 not eq @array2';
}

(можно скачать файл)

И что же вы думаете печатает такая программа?

Подсказка

Показать

К сожалению, программа печатает @array1 not eq @array2 и не выдает никаких предупреждений, даже если включить прагмы strict и warnings.

Подсказка-2

Показать

perldoc perlop

Разоблачение

Показать

Дело в приоритете операций. Вычисление происходите не так:

join('*', @array1) eq join('*', @array2)

, а так:

join'*', (@array1 eq join('*', @array2)

А это, конечно, совсем не то, что имел в виду программист.

Стоило бы по крайней мере добавить скобки в условие, чтобы обеспечить правильный порядок вычисления. А может быть, реализовать другую фунцию для сравнения массивов. Или использовать модуль Data::Compare. Или комбинацию any и pairwise из List::MoreUtils.

Из наших читателей первый и самый полный ответ прислал Anatoliy nuclon@