Перейти к основному содержанию
Тема: Грабли Perl 6 (Прочитано 2500 раз) предыдущая тема - следующая тема

Грабли Perl 6

Давайте в этой теме поговорим о подводных камнях 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 !
Цитата
multi sub slurp(IO::Handle:D $fh = $*ARGFILES, |c)
multi sub slurp(IO() $path, |c)
method slurp(IO::CatHandle:D:)
method slurp(IO::Handle:D: :$close, :$bin)
multi method slurp(IO::Path:D: :$bin, :$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



продолжение следует ...

 

Re: Грабли Perl 6

Ответ #1
Забавно (эту штуку, и не только эту, должны исправить)
> my $t = (1,2,3);
(1 2 3)
> my @t = $t;
[(1 2 3)]
> @t = <1 2 3>;
[1 2 3]

Re: Грабли Perl 6

Ответ #2
> say my @i.so
False
> say my @i[3].so
True

Потому что:
> my @a[3];
[(Any) (Any) (Any)]
> @a.so
True
> say (my @a[3]).so
True

Развёрнутый ответ здесь: https://stackoverflow.com/a/67374072/1577548