caller EXPR
caller

返回当前纯 Perl 子程序调用的上下文。在标量上下文中,如果存在调用者(即,如果我们在子程序或 evalrequire 中),则返回调用者的包名,否则返回未定义值。caller 永远不会返回 XS 子程序,并且会跳过它们。下一个纯 Perl 子程序将出现在 caller 的返回值中,而不是 XS 子程序。在列表上下文中,caller 返回

   # 0         1          2
my ($package, $filename, $line) = caller;

__FILE____LINE__ 一样,此处返回的文件名和行号可能会被 "Plain Old Comments (Not!)" in perlsyn 中描述的机制更改。

使用 EXPR,它返回一些调试器用来打印堆栈跟踪的额外信息。EXPR 的值指示在当前帧之前回溯多少个调用帧。

   #  0         1          2      3            4
my ($package, $filename, $line, $subroutine, $hasargs,

   #  5          6          7            8       9         10
   $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
 = caller($i);

这里,$subroutine 是调用者调用的函数(而不是包含调用者的函数)。请注意,如果该帧不是子例程调用,而是 eval,则 $subroutine 可能为 (eval)。在这种情况下,将设置额外的元素 $evaltext 和 $is_require:如果该帧是由 requireuse 语句创建的,则 $is_require 为 true,$evaltext 包含 eval EXPR 语句的文本。特别是,对于 eval BLOCK 语句,$subroutine 为 (eval),但 $evaltext 未定义。(另请注意,每个 use 语句都会在 eval EXPR 帧内创建一个 require 帧。)如果该特定子例程恰好已从符号表中删除,则 $subroutine 也可能为 (unknown)$hasargs 如果为该帧设置了 @_ 的新实例,则为 true。$hints$bitmask 包含调用者编译时的语义提示。$hints 对应于 $^H$bitmask 对应于 ${^WARNING_BITS}$hints$bitmask 值可能会在 Perl 版本之间发生变化,并且不适合外部使用。

$hinthash 是一个指向哈希的引用,该哈希包含调用者编译时 %^H 的值,如果 %^H 为空,则为 undef。不要修改此哈希的值,因为它们是 optree 中存储的实际值。

请注意,唯一可见的调用帧类型是子例程调用和 eval。其他形式的上下文,例如 whileforeach 循环或 try 块,对 caller 来说并不重要,因为它们不会改变 return 表达式的行为。

此外,当从 DB 包中以列表上下文调用时,并且带有参数,caller 会返回更详细的信息:它将列表变量 @DB::args 设置为调用子例程时使用的参数。

请注意,优化器可能会在 caller 有机会获取信息之前优化掉调用帧。这意味着 caller(N) 可能会返回与您期望的调用帧信息不一致的信息,对于 N > 1。特别是,@DB::args 可能包含上次调用 caller 时的信息。

请注意,设置 @DB::args尽力而为,旨在用于调试或生成回溯,不应依赖它。特别是,由于 @_ 包含对调用者参数的别名,Perl 不会复制 @_,因此 @DB::args 将包含子例程对 @_ 或其内容所做的修改,而不是调用时的原始值。@DB::args@_ 一样,不保存其元素的显式引用,因此在某些情况下,其元素可能已被释放并重新分配给其他变量或临时值。最后,当前实现的一个副作用是,shift @_ 的效果通常可以撤销(但不能撤销 pop @_ 或其他拼接,并且不能撤销如果对 @_ 的引用已被获取,并且受重新分配元素的警告的约束),因此 @DB::args 实际上是 @_ 的当前状态和初始状态的混合。买家自负。