通常会使用 callframe 子例程从程序的当前状态捕获 CallFrame
。
my = callframe;say "The above line of code ran at :.";
如果没有参数,callframe 将为你提供调用 callframe
的行的帧信息。文件和行注释将与 $?FILE
和 $?LINE
中的注释相同。
但是,你可以将一个数字传递给 callframe
以指定不同的帧级别。正数将向上移动帧级别。负数将向下移动到 callframe
方法和类本身,在它们运行以构造此信息时。
帧本身不一定只匹配方法或子例程调用。Raku 也为块等构造帧,因此,如果你需要特定方法调用的 callframe,请不要假设它是一个固定数量的向上级别。
每个帧都存储 注释,包括 文件 和 行 注释,这些注释具有用于直接访问它们的便捷方法。你还可以使用 code 方法检索对当前执行帧的代码块的引用。该帧还捕获帧中存储的所有词法变量,可以通过在帧对象上调用 my 来获取这些变量。
以下是一个简短的示例,它将找到调用例程并使用 callframe
接口打印调用者的包。
sub calling-frame()calling-frame;
如果你只需要跟踪调用者信息,Backtrace
可能提供更好的获取信息的方法。CallFrame
包含有关特定帧的更多信息,但提供了一个繁琐的接口来枚举调用堆栈。
方法§
注意 从 6.d 版本开始,可以在 CallFrame
上调用 .raku
(2019.11 版本之前的 .perl
)。
方法代码§
method code()
返回当前块的可调用代码。当在 callframe(0)
返回的对象上调用时,这将与 &?BLOCK
中找到的值相同。
my ;for ^3 ;say .code()
在本例中,$frame
变量将保存循环中块的 Code
。
方法文件§
method file()
这是查找 file
注释的快捷方式。因此,以下代码打印 True
。
my = callframe(0);say .file eq .annotations<file>;
方法行§
method line()
这是查找 line
注释的快捷方式。例如,以下两个调用是相同的。
say callframe(1).line;say callframe(1).annotations<line>;
方法注释§
method annotations()
返回一个包含调用者注释的 Map
,即 line
和 file
。获取注释信息的一种更简单的方法是使用其中一个便捷方法。
say callframe.annotations.^name; # OUTPUT: «Map»say callframe.annotations<file> eq callframe.file; # OUTPUT: «True»
方法 my§
method my()
返回一个 Hash
,其中命名了与帧词法作用域关联的所有变量及其值。
sub some-valuemy = some-value();say .my<$the-answer>; # OUTPUT: «42»
例程§
子 callframe§
sub callframe(Int = 0)
返回给定级别的 CallFrame
对象。如果未给出级别,则默认级别为 0。正级别向上移动帧堆栈,负级别向下移动(进入对 callframe
的调用并更深入)。
如果给定级别的调用信息不存在,则返回 Mu
。负级别可能会导致异常。