加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl:匿名子程序中的原型

发布时间:2020-12-15 21:42:23 所属栏目:大数据 来源:网络整理
导读:我目前正在学习有关类型和名称空间的Perls系统.所以我写了一个模块,它接受一个常量的值和名称两个参数,并将常量输出到调用者. $package变量等于caller [2]. *{"$package::$name"} = sub () { return $value; }; 上面的代码完成了将匿名子例程导出到调用者符
我目前正在学习有关类型和名称空间的Perls系统.所以我写了一个模块,它接受一个常量的值和名称两个参数,并将常量输出到调用者. $package变量等于caller [2].
*{"$package::$name"} = sub () { return $value; };

上面的代码完成了将匿名子例程导出到调用者符号表中的工作.因为我的目标是构建我自己的常量实现,子例程有一个空原型,这意味着它是一个只读子程序.

但这是我的问题:原型不起作用.所以

print &TestConst; #works well
print TestConst(); #works well
print TestConst; #Name "main::TestConst" used only once: possible typo at testscript.pl line 7.

我的想法有什么问题吗?还有另一种方法吗?

解决方法

您可以在运行时定义所需的所有符号,但原型只会影响之后编译的代码,因为原型会影响对子调用的解析和编译方式.例如:
use strict;
use warnings;

package Foo;

BEGIN {
    *Foo::bar = sub () { 42 };
}

*Foo::baz = sub () { 43 };

my $bar = bar;
my $baz = baz;

print "bar = [$bar],baz = [$baz]n";

如果我们运行它,它会死于:

Bareword “baz” not allowed while “strict subs” in use at tprot.pl line
13.

这是由strict引起的编译时错误:编译器看到符号baz并且不知道它是什么,因为typeglob * Foo :: baz直到运行时才被改变.但是bar工作正常,因为它是在BEGIN块中定义的,它在编译期间立即执行.

IOW,因为裸字是模棱两可的,Perl需要在编译时知道它是sub还是其他东西.因此,您可以在导入期间(在隐式BEGIN块中执行)安装这些,但不能在运行时安装.

另外,原型会影响编译语义;一个常量子程序(如constant.pm所做的那样)被优化掉了.其他原型导致解析器改变其行为(例如可以接受代码块的subs.)编译器必须在代码中实际遇到对sub的调用之前知道所有这些内容,因此可以正确解析它们.在解析完所有内容后,代码就会运行.

使用显式parens或带符号调用sub不具有此限制,因为Perl在运行时足够聪明,知道这些是子例程调用,并在符号表中动态查找它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读