perl闭包和$ _ [英] perl closures and $_

查看:82
本文介绍了perl闭包和$ _的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在不熟悉的编程语言中学习的第一件事是如何处理闭包。它们的语义往往与语言处理范围和各种其他棘手位相互交织,因此理解它们揭示了语言的其他几个方面。另外,闭包是一个非常强大的结构,通常会减少我必须键入的样板数量。所以我正在解决perl关闭,我偶然发现了一个小毛病:

  my @closures; 
foreach(1..3){
#create some closure
push @closures,sub {sayI'll remember $ _; };
}
foreach(@closures){
#调用闭包看看他们记得什么
#结果不明显
& {$ _}() ;
}

当我写上述代码时,我期待看到

$我会记得1
我会记得2
我会记得3
b
$ b

但是我有我会记住CODE(0x986c1f0)



上面的实验表明, $ _ 是非常上下文相关的,如果它出现在闭包中,那么它的值不固定在闭包的创造。它的行为更像一个引用。

解决方案

只关闭词法变量; $ _ 通常是一个全局变量。
在5.10及以上版本中,你可以说 my $ _; 使它在给定范围内是词法的(虽然在5.18中这被追溯性地声明为实验性的,



这将产生您期望的输出:

  use strict; 
使用警告;
use 5.010;
my @closures;
foreach my $ _(1..3){
#create some closure
push @closures,sub {sayI'll remember $ _; };
}
foreach(@closures){
#调用闭包看看他们记得什么
#结果不明显
& {$ _}() ;
}


One of the first things I try to learn in an unfamiliar programming language is how it handles closures. Their semantics are often intertwined with how the language handles scopes and various other tricky bits so understanding them reveals several other aspects of the language. Plus, closures are a really powerful construct and often times cut down on the amount of boilerplate I have to type. So I was messing around with perl closures and I stumbled upon a little gotcha:

my @closures;
foreach (1..3) {
  # create some closures
  push @closures, sub { say "I will remember $_"; };
}
foreach (@closures) {
  # call the closures to see what they remember
  # the result is not obvious
  &{$_}();
}

When I wrote the above code I was expecting to see

I will remember 1
I will remember 2
I will remember 3

but instead I got I will remember CODE(0x986c1f0).

The above experiment revealed that $_ is very context dependent and if it appears in a closure then it's value is not fixed at the point of the closure's creation. It behaves more like a reference. What other gotchas should I be aware of when creating closures in perl?

解决方案

Closures only close over lexical variables; $_ is normally a global variable. In 5.10 and above, you can say my $_; to have it be lexical in a given scope (though in 5.18 this was retroactively declared to be experimental and subject to change, so better to use some other variable name).

This produces the output you expected:

use strict;
use warnings;
use 5.010;
my @closures;
foreach my $_ (1..3) {
  # create some closures
  push @closures, sub { say "I will remember $_"; };
}
foreach (@closures) {
  # call the closures to see what they remember
  # the result is not obvious
  &{$_}();
}

这篇关于perl闭包和$ _的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆