Perl有一个未定义函数的概念。已声明但未定义的函数。
sub foo;
foo(); # Undefined subroutine error
bar(); # Undefined subroutine error
这个函数foo
现在存在于符号表中,它可以用来解析方法调用。但是为什么这个“特征”会存在呢?在C语言中,这是因为函数是类型检查的,有时您希望在定义之前进行调用(例如解决循环依赖关系)。但是Perl没有这样的特性,所有的函数符号都是在运行时而不是编译时解析的。
>
如果不是原型,为什么它会存在?
为什么在方法解析中使用未定义的子程序?为什么不完全忽略它们呢?你不能调用它们,就我所知(最多)它们是内部实现细节?这就是为什么如果函数没有定义,我们就不能继续方法解析,就好像它不存在一样(看起来就不那么令人困惑了)。
这为我节省了很多调试:
sub AUTOLOAD
{
my (undef,$filename,$lineno) = caller;
my ($fn) = basename($filename);
logmsg('E',"Undefined reference ($fn/$lineno): ref=$AUTOLOAD, refer=$ENV{HTTP_REFERER}");
}
我想说,这和其他类型的人一样;只是它如何被解析的产物。
my $hr = { a => 1 }; # $hr name introduced at compile time, assigned or not
所以也一样
sub name { ... }; # "name" "declared" at compile time
只说子名字
与“我的$hr”差不多
--然后有一个没有定义的符号。
我不知道解析器是如何工作的,但我猜它必须先使用子名称
,然后再“绑定”定义,因此偶然情况下,我们也可以只说子名称
并具有该名称。
我的意思是说,这是“原因”,根据“但是为什么这个“特征”会存在?”
但是,一旦编译器提前知道有一个子系统具有该名称,那么这个事实可能会有各种用途。
这是关于原型的,函数的声明(或不声明)在编译时确实有影响。考虑
print foo + 42;
单独来看,这相当于print('foo'42)
-foo
是一个“空话”。如果您启用了严格的'subs'
,它会给您一个编译错误,告诉您禁止使用裸字。
sub foo;
print foo + 42;
这相当于打印(foo(42));编译器知道foo
是一个子系统,它没有原型,因此它以“list op”的方式消耗它之后的所有内容,然后是术语42
。
sub foo();
print foo + 42;
这相当于打印(foo()42);编译器知道foo
有一个原型,它不带任何参数,因此不会查找任何参数,foo
和42
将是运算符的操作数。
sub foo($);
print foo + 42;
与案例2类似,这相当于打印(foo(42))。我想可能有一个测试我可以用来区分他们。
重要的是,sub是否已知在编译时都会产生影响,Perl为您提供了在定义sub主体之前声明该事实的选项,尽管它可能很少需要。
至于为什么它会影响方法解析顺序——很可能是副作用,但这并没有错。前向声明sub意味着您打算在编译完成之前提供定义。如果不这样做,那么在尝试调用它时将出现运行时错误。在我看来,如果这样的声明在MRO中的一个包中,那么这意味着“这里应该有一个方法,但我忘记了”,在MRO到达该包时,您会收到一个错误。
最近为什么const对象需要用户提供的默认构造函数?被标记为为什么C需要用户提供的默认构造函数来默认构造const对象?。我正在使用coliru和rextexter来测试各种版本的gcc(g-4.7、g-4.8、g-4.9)和clang(3.4和3.5),以查看此行为是否在较新版本的编译器中引入。这里我们有两个测试用例,分别来自两个问题: 和: 叮当出错: 预期但不是gcc,也不是MSVC。我想我
问题内容: 我可以用修饰符声明以下程序包,但似乎对任何内容都没有影响: 所以我的问题是,在程序包清算之前添加修饰符会做什么,为什么编译器会允许它? 更新 :似乎与Eclipse捆绑在一起的编译器是一个问题,就像其他人提到的那样,这是使用Sun的JDK的编译器错误。 问题答案: 他们不是。您正在使用哪个编译器?
在这里,我们希望收件人重定向我们的网站(endpoint与唱staus的文档),但从API文档,我们没有得到任何可行的解决方案。 是否有任何方法重定向收件人后唱的文件(不使用客户端用户ID或从电子邮件)?
问题内容: 作为ASP.NET MVC 2 Beta 2更新的一部分,默认情况下不允许JSON GET请求。看来您需要将字段设置为从控制器返回对象之前。 这背后的原因是什么?如果我正在使用JSON GET尝试进行一些远程验证,那么我应该使用其他技术吗? 问题答案: DenyGet默认的原因是在MSDN上,该链接提供了Phil Haack的博客 的详细信息。看起来像跨站点脚本漏洞。
考虑以下代码: 这里无论有什么值,
我正在从文档中学习反应,但不确定在这个例子中超级()做什么。通常,它不需要传递给创建新实例的参数,然后调用React吗?组件的构造函数方法将这些参数合并到实例中?没有任何争论它是做什么的?