Даже если вы явно вызвали .sink
для этого возвращаемого значения, Failure
не взорвется:
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink.sink;
say "Did not explode";
# OUTPUT: Did not explode
Взрыв в вашем коде происходит во время воспроизведения .gist
во время say
вызова, который проходит через первые 100 элементов вашего Array
и вызывает .gist
на них. Когда он делает это на элементе Failure
, он взрывает его.
Вы путаете погружение самого объекта списка и отдельных значений, которые он содержит. Вы правильно упомянули, что List.sink
не работает, но Seq.sink
потребляет сам себя, но он также не взорвется, потому что потоплен только Seq
, а не отдельные его элементы: (+"a", 42).Seq.sink
Если вы хотите вызвать потенциальные Failure
взрывы, вы можете:
1: use fatal
. Это приведет к тому, что компилятор приведет к фатальным сбоям, что приведет к их детонации во многих местах, где передается Failures
. Это лексическая прагма, и она также автоматически включается в try {}
блоках.
use fatal;
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink;
# OUTPUT:
# boo!
# in block <unit> at
2: Hyper over .self
вызов метода. Он предоставляется Mu
(поэтому наследуется всеми объектами) и просто возвращает self
, так что это неоперация (кроме выполнения decont ). Однако, поскольку большинство методов, вызываемых на вооруженных Failure
, вызывают их детонацию, вызов .self
для них приведет к их взрыву.
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink».self;
# OUTPUT:
# boo!
# in block <unit> at
Как мне отладить эти функции с помощью отладчика Perl 6 или модуля?
Не используйте отладчики самостоятельно, но perl6-debug-m
должен поставляться с предустановленной вашей установкой Rakudo. Требуется установить модуль Debugger::UI::CommandLine
. И вы просто используете это вместо perl6
для запуска вашей программы, и она должна предложить некоторые инструкции в командной строке о том, что она делает. На нем также есть сообщение в блоге и видео (для воспроизведения требуется Flash).
Существует также недавно выпущенный альфа-качество App::MoarVM::Debug
, которое позволяет отлаживать программы даже удаленно. Его прелесть в том, что он позволяет создавать дампы объектов и перемещаться по ним во время работы программы, поэтому, если вы справитесь с ее интерфейсом, это может быть удобно.
Лично я отлаживаю, просто используя подпрограмму dd
, чтобы выгрузить вещи в стратегических точках и посмотреть, содержит ли то, что я ожидаю, в них.
Как я могу узнать, действительно ли вызывается этот List.sink или, вообще, вызывается ли приемник, когда объект находится в контексте приемника?
Вы можете добавить роль, используя операторы does
или but
, которые предоставляют метод sink
, который делает то, что вы можете наблюдать. Нравится напечатать что-нибудь:
sub foo {
return [<a b c>] does role {
method sink { say "sink called" }
}
}
foo
# OUTPUT: sink called
Более продвинутым методом будет дамп постоптимизации Дерево QAST и проверка наличия ожидаемых вызовов. Модуль CoreHackers::Q
облегчает визуализацию выгруженного дерева QAST.
P.S .: по теме подразумеваемой утечки, стоит отметить R # 1571 , которая перечисляет несколько ошибок с ним и предлагает полностью переработать внутренние системы обработки утечки.
¹ - точнее, Seq.sink
вызывает .sink-all
на своем Iterator
, который по умолчанию просто потребляет значения, но пользовательские итераторы могут переопределить этот метод, чтобы он тоже не выполнялся .