即使$ var不是带有*
twigil的动态变量,此代码也会打印出“ Duo”:
our $var="Duo";
sub sub1() {
say $*var;
}
sub1();
#output is 'Duo'
在开始时添加unit package ABC;
会导致编译时错误“找不到动态变量$ * var”:
unit package ABC;
our $var="Duo";
sub sub1() {
say $*var;
}
sub1();
# compile time error
在这种情况下,添加* twigil可使变量可访问。
为什么有区别?
编辑1:
使用my
代替our
是有或没有软件包的编译时错误,即使按照我的理解这意味着相同的词法范围。
是要动态使用的变量,需要这样明确声明(就像我可以找到的所有示例一样)。如果是这样,our
如何使上述工作正常进行?我很困惑。
编辑2:
我认为以下内容证明了我感到困惑的原因:
our $var="non dynamic"; #1
{say $*var;}
our $*var="dynamic"; #2
{say $*var;}
#With #2 commented output is
#non dynamic
#non dynamic
#
#With #2 in place output becomes
#(Any)
#dynamic
在第一种情况下(注释#2),我正在动态访问非动态变量(两次)。
在第二种情况下,our $var
变量在声明our $*var
时被破坏,而访问相同的动态变量则解析为两个单独的变量。
答案 0 :(得分:6)
好像动态变量在GLOBAL
name space中查找。因此,以下工作有效:
unit package ABC;
$GLOBAL::var="Duo";
sub sub1() {
say $*var;
}
sub1();
#output is 'Duo'
第一个示例起作用的原因是(根据documentation):
用户程序从
GLOBAL
包开始,因此“我们的”声明 在主线代码中,默认情况下进入该程序包。
答案 1 :(得分:6)
动态变量查找从概念上讲在所有动态作用域中进行。动态范围首先是PROCESS::
,然后是GLOBAL::
,然后是程序具有的任何动态范围。
因此,当您查找动态变量时,它将首先从当前向下查找所有动态范围。如果找不到它,它将在GLOBAL::
中查找,如果找不到,则将在PROCESS::
中查找。
例如,如果要在STDOUT上打印某些内容,它将查找$*OUT
动态变量。如果您没有在动态范围中的某处定义一个,它将使用PROCESS::
中的一个:
dd PROCESS::<$OUT>;
# IO::Handle element = IO::Handle.new(path => IO::Special.new("<STDOUT>")...)