is Nil
Failure
是一个软或未抛出的 Exception
,通常通过调用 &fail
生成。它充当 Exception
对象的包装器。
Sink(void)上下文会导致 Failure
抛出,即变成常规异常。use fatal
语用程序会在语用程序作用域内的所有上下文中导致这种情况发生。在 try
块 内,use fatal
会自动设置,并且你可以使用 no fatal
来禁用它。
这意味着 Failures 通常仅在通常会产生右值的代码的情况下才有用;在经常在 sink 上下文中调用的代码中,Failures 与 Exceptions 几乎等效(即,对于其副作用,例如使用 say
)。
类似地,你通常应该仅在通常预期返回某些内容的代码内使用 &fail
。
检查 Failure 是否为真(使用 Bool
方法)或是否已定义(使用 defined
方法)会将失败标记为已处理,并导致它不再在 sink 上下文中抛出。
你可以调用 handled
方法来检查失败是否已处理。
对未处理的失败调用方法会传播失败。规范规定结果是另一个 Failure
;在 Rakudo 中,它会导致失败抛出。
因为 Failure 是 Nil
,它是未定义的,所以安全执行可能失败的代码的常用习惯用法是使用 with/else
语句
sub may_fail( --> Numeric )with may_fail() ->else
方法§
方法 new§
multi method new(Failure:)multi method new(Failure:)multi method new(Failure: Exception \exception)multi method new(Failure: )multi method new(Failure: |cap (*))
返回一个新的 Failure
实例,其有效负载作为参数给出。如果在 Failure
对象上不带参数调用它,它将抛出;在类型值上,它将创建一个没有有效负载的空 Failure
。后者可以是 Exception
或 Exception
的有效负载。典型的有效负载将是一个带有错误消息的 Str
。还接受有效负载列表。
my = Failure.new(now.DateTime, 'WELP‼');say ;CATCH# OUTPUT: «X::AdHoc: 2017-09-10T11:56:05.477237ZWELP‼»
方法 handled§
method handled(Failure: --> Bool) is rw
对于已处理的失败返回 True
,否则返回 False
。
sub f() ; my = f; say .handled; # OUTPUT: «False»
handled
方法是一个 左值,请参见 例程特性 is rw
,这意味着你还可以使用它来设置已处理状态
sub f()my = f;.handled = True;say .handled; # OUTPUT: «True»
方法 exception§
method exception(Failure: --> Exception)
返回失败包装的 Exception
对象。
sub failer() ;my = failer;my = .exception;put "$ex.^name(): $ex";# OUTPUT: «X::AdHoc: Failed»
方法 self§
method self(Failure: --> Failure)
如果调用者是 已处理 的 Failure
,则按原样返回它。如果没有处理,则抛出其 Exception
。由于 Mu
类型 提供 .self
适用于每个类,调用此方法是爆炸性地过滤掉 Failures 的一种便捷方法
my = '♥'.Int;# $num1 now contains a Failure object, which may not be desirablemy = '♥'.Int.self;# .self method call on Failure causes an exception to be thrownmy = '42'.Int.self;# Int type has a .self method, so here $num3 has `42` in it(my = '♥'.Int).so;say .self; # OUTPUT: «(HANDLED) Cannot convert string to number…»# Here, Failure is handled, so .self just returns it as is
方法 Bool§
multi method Bool(Failure: --> Bool)
返回 False
,并将失败标记为已处理。
sub f() ;my = f;say .handled; # OUTPUT: «False»say .Bool; # OUTPUT: «False»say .handled; # OUTPUT: «True»
方法 Capture§
method Capture()
如果调用者是类型对象或 已处理的 Failure
,则抛出 X::Cannot::Capture
。否则,抛出调用者的 异常。
方法 defined§
multi method defined(Failure: --> Bool)
返回 False
(失败在官方上是未定义的),并将失败标记为已处理。
sub f() ;my = f;say .handled; # OUTPUT: «False»say .defined; # OUTPUT: «False»say .handled; # OUTPUT: «True»
方法 list§
multi method list(Failure:)
将失败标记为已处理,并抛出调用者的 异常。
子例程 fail§
multi fail(--> Nil)multi fail(*)multi fail(Exception --> Nil )multi fail( --> Nil)multi fail(|cap (*) --> Nil)multi fail(Failure --> Nil)multi fail(Failure --> Nil)
退出调用 Routine
,并返回一个 Failure
对象,该对象包装异常 $e
- 或对于 cap
或 $payload
形式,一个由 @text
拼接构成的 X::AdHoc
异常。如果调用者通过 pragma use fatal;
激活了致命异常,则抛出异常,而不是将其作为 Failure
返回。
# A custom exception definedis Exceptionsub copy-directory-tree ()# A Failure with X::AdHoc exception object is returned and# assigned, so no throwing Would be thrown without an assignmentmy = copy-directory-tree("cat.jpg");say .exception; # OUTPUT: «cat.jpg is not a directory»# A Failure with a custom Exception object is returned= copy-directory-tree('foo');say .exception; # OUTPUT: «This directory is forbidden: 'foo'»
如果使用通用 Failure
调用它,则抛出临时未定义失败;如果它是一个已定义的 Failure
,它将被标记为未处理。
sub re-failmy = re-fail;say .handled; # OUTPUT: «False»