Недавно я потратил много времени на отладку скрипта, и когда я наконец нашел проблему, это было из-за кода, который был похож на это:
class Foo {
has $.bar;
method () {
# do stuff
$!.bar;
}
}
Оказалось, проблема была в том $!.bar
, что должно было быть $!bar
или $.bar
. Я понял это.
Но почему это не умирает ?
Глядя на это более подробно, похоже , вопрос здесь в том , что я пытаюсь вызвать (несуществующий) метод bar
на $!
, который в данный момент является , Nil
потому что не было никаких ошибок.
И похоже, что на самом деле я могу вызвать любой метод, который мне нужен, Nil
и все они молча возвращаются Nil
, включая такие вещи, как Nil.this-is-a-fake-method
и Nil.reverse-entropy(123)
.
Это особенность? Если так, в чем причина?
Nil
возвратеNil
, которыйNil
распространяется вниз по цепочке вызова метода». Таким образом, предполагается, что вы можете обойтись$foo.Bar().Baz().Blah()
без нуля тестов на каждом шаге или специального?.
вида оператора (если вы правильно обрабатываете ноль в конце). Я отредактирую это, спасибо.Nil
который не содержит ошибок и просто отбрасывает больше,Nil
получает довольно широкое применение в Obj-C и NS Frameworks, где он используется аналогичным образом - позволяет выполнять цепные вызовы, которые продолжают передаваться по Nil. Я не знаю точных штрафов за производительность исключений и их перехвата, но я предполагаю, чтоNil
связывание может быть более эффективным, если менее гибким.Nil
классе есть методFALLBACK
docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) , который возвращаетNil
. В основном, непосредственно перед тем, как генерируется исключение, потому что метод не может быть найден, проверкаFALLBACK
выполняется и вызывается, если доступно.Этот вопрос (и ответ Хоббса) также заставил меня чувствовать себя ... неловко: я в конце концов обнаружил https://docs.raku.org/language/traps : он объясняет, что присваивание
Nil
обычно приводит к другому значениюAny
. Следующее базовое взаимодействие REPL также демонстрирует это:((разница между
=
и:=
рассматривается здесь: https://docs.raku.org/language/containers#Binding ))... так что общая идея заключается в том, что «отсутствующее значение или доброкачественный сбой» гораздо менее распространен в обычном коде, чем я (и, возможно, вы тоже?) внезапно опасался: однако, это происходит, когда вы собираетесь работать с регулярным выражением соответствует непосредственно и в вашей конкретной случайной ситуации, связанной с непосредственным вызовом методов
$!
.Это сделало меня более осведомленным о разнице между
Nil
иAny
, и предоставленное обоснование имело больше смысла для меня.источник
Nil
устанавливает контейнер в состояние по умолчанию. Вы можете изменить значение по умолчанию.my $foo is default(42) = 5;
$foo = Nil;
say $foo; # 42