Давайте в этой теме поговорим о подводных камнях Perl 6.
В каждом языке программирования есть конструкции, которые делают не то что ожидал получить программист.
1) Сравнение списков:
(1,2,3) == (1,2, ('qwerty'))
# True
['spam', 42] == ['spam', 425]
# True
4 == (1,2,3,4)
# True
{bar => 'spam', foo => 42} == {bar => 'spam', foo => 424}
# True
Оператор == при сравнении списков и хэшей смотрит на список или хэш как на число и поэтому он сравнивает не содержимое, а количество элементов! Чтобы сравнивать содержимое списков и хэшей нужно использовать оператор eqv
https://stackoverflow.com/a/40877528/1577548
Правильное сравнение:
(1,2,3) eqv (1,2, ('qwerty'))
# False
[1,2,3] eqv [1,2,34]
# False
4 eqv (1,2,3,4)
# False
2) Также в тестах, чтоб сравнить списки и хэши, не используйте функцию is. Вместо неё используйте is-deeply.
3) head
say <a b c>.head(.elems - 1)
работает как:
say <a b c>.head($_.elems - 1)
Лучше не гадать и вообще не использовать функцию или блок кода в качестве параметра для метода head. Если будете извращаться с методом head, то тщательно проверяйте ожидаемый результат и реальный.
https://docs.raku.org/routine/head
4) не во всех случаях метод slurp имеет параметр :enc !
5) Пробелы важны:
flat (ords("\t\b\o33\o14"), 32..126, 128..255).elems # (3)
flat(ords("\t\b\o33\o14"), 32..126, 128..255).elems # 227
6) ! и not (правильно с not):
! 1 == 15; # False
not 1 == 15; # True
7) метод comb
Внимательно читайте документацию по этому методу и проверяйте переменную какого типа ему передаёте!
Мегаполезный метод comb может выдать не то, что ожидаете получить:
say 'abcd7efgh7ijk'.comb(7).join('-'); # abcd7ef-gh7ijk
say 'abcd7efgh7ijk'.comb('7').join('-'); # 7-7
8) В анонимных функциях вида my $func = -> { }; не используйте ключевое слово return
Например (тащемта):
sub test()
{
my $f = -> { say 2; return; };
$f();
say 1;
}
test();
# 2
В этом примере return работает для родительской функции, понимаете?
9) Если вам не нужны пустые строки на краях файла, то используйте trim:
my $content = 'input.txt'.slurp.trim;
Я недавно полдня не мог понять, почему не работает мой код, а оказалось из-за пустой строки в самом конце длинного файла.
10) Контейнеры
Ссылка на документацию: https://docs.raku.org/language/containers#Scalar_containers_and_listy_things
Пример:
my $a = (1, 2, 3);
# (1 2 3)
say $a.elems;
# 3
say '- ', $_ for $a;
# - (1 2 3)
Заметили?
Теперь применим оператор деконтейнеризации <>
say '- ', $_ for $a<>;
# -1
# -2
# -3
Символ @ также можно использовать в качестве префикса для приведения аргумента к списку, таким образом удаляя скалярный контейнер:
say '- ', $_ for @$a;
# -1
# -2
# -3
10) Функция all
Пример:
my @a = ();
say so all(@a) # True, потому что 0 ложных в массиве
Чтобы проверить условие «все, но хотя бы один», вы можете использовать @a && all(@a)
my @a = ();
say so @a && all(@a); # False
продолжение следует ...