首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >perl6 subs是真的有词法作用域,还是有额外的?

perl6 subs是真的有词法作用域,还是有额外的?
EN

Stack Overflow用户
提问于 2019-06-27 01:43:35
回答 1查看 121关注 0票数 7

如果我有一个如下所示的块:

代码语言:javascript
复制
{
   say $myVar;
   my $myVar=1;
}

我得到了预期的错误:

代码语言:javascript
复制
Variable '$myVar' is not declared 

但是以类似的方式使用sub

代码语言:javascript
复制
{
    test();
    my sub test() {
        say "Hello";
    }
}

此命令运行时不会出现错误,并打印:

代码语言:javascript
复制
Hello

在封闭的块之外,$myVartest都不可见,因此从这个意义上说,它们都是词法作用域。

由于test在代码中的位置之前已定义并可用,因此sub必须将其声明“提升”到块的顶部。然而,我找不到一个参考资料来支持这一点。

提出这个问题的原因是查看了perl中的词法作用域my subs,它在上面第二种情况的perl版本中给出了一个“未定义的子例程”错误。在我对词法作用域的理解中,这是我所期望的。

我不假思索地使用它。编写一些测试代码,稍后将其包装到我的文件底部声明的sub中,并调用文件中前面的sub。一切正常!

这确实引出了一个问题: perl6 subs真的在这种意义上限定了词法范围吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-27 03:17:41

当Perl6遇到函数调用时,它会记录下来,但不会检查函数是否在那里。

所以下面的代码将会被编译,但实际上不会工作。(该函数在被调用的地方不可用。)

代码语言:javascript
复制
foo 1;
my &foo = &say;

在下面的代码中,编译器做了同样的事情,但是优化器意识到它甚至找不到任何地方对该函数的引用。(因此优化器会导致它在编译过程中失败。)

代码语言:javascript
复制
bar 1;

与其他变量不同的原因是,很多时候,您可能有一个函数依赖于另一个函数,或者您希望将这些函数放在其余代码之后。

此外,函数的代码通常在编译时是已知的,而变量的值直到赋值之后才知道。(赋值发生在运行时。)

基本上,人们使用变量和函数的方式是不同的,所以它们的工作方式也略有不同。

没有必要在使用它们之前要求它们被声明,所以这个限制被删除了。

在Perl5中,函数根据其原型修改解析器,因此编译器需要在使用它们之前查看声明,以便知道应该如何解析它们。

代码语言:javascript
复制
use v5.10;

sub foo ();
sub bar;

say foo + 1; # foo() + 1 # foo is compiled as a term/constant
say bar + 1; # bar( +1 )

sub foo () { 2 }
sub bar { $_[0] + 2 }

在Perl6中,所有函数都像接受列表一样进行编译,因此不需要预先声明它们。

代码语言:javascript
复制
use v6;

# these two lines don't really change anything.
sub foo () {...}
sub bar ($) {...}


say foo + 1; # foo( +1 ) # optimization failure (too many arguments)
say bar + 1; # bar( +1 )

sub foo () { 2 }
sub bar ( $a ) { $a + 2 }
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56778434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档