【问题标题】:perl closured variable returns empty stringperl 封闭变量返回空字符串
【发布时间】:2023-03-15 17:05:02
【问题描述】:

我无法用看似简单的表达式来解释 perl 的行为。 我已将我的问题与这段相对较短的 perl 代码隔离开来。 make_peak 返回一个函数,该函数跟踪信号 v() 的最大值并将该最大值保存在封闭变量 $max 中。

事实上,代码打印“2”。但是,如果我删除 kludgy ""。在 return statemnt 中,$p->() 返回 uundef?

use strict;

our $i=0;

sub v($) {
  $i=$i+1;
  return $i;
}

sub make_peak($)
{
  my $vi=$_[0];
  my $max=-1e35;
  return sub() {
    $max=v($vi) if v($vi)>$max;
    return "".$max; # ??? without the kludge returns empty line
  };
}

my $p=make_peak(10);

my $m=$p->();
print $m;

【问题讨论】:

  • 你的目标是什么?这段代码结合了各种变量作用域,很难理解
  • 我正在尝试处理信号,它由函数 v() 表示。我需要计算这个信号的几个特征。 (示例——最大值,如图所示)。由于我需要有许多不同的特征,并且我想在不同的信号 v() 上应用它们的不同组合,所以我尝试将它们作为 lambdas 来执行,但遇到了这种奇怪的行为。
  • 我没有观察到您报告的行为。 "".$max$max 都将返回 2
  • 从您的示例中,v($vi) 中的 $vi 被忽略。我认为在这个例子中这是故意的。其次,每次调用 v() 时 $i 都会递增,所以当 v($vi)>$max 被调用时,$i 会递增到 1,然后在 $max=v($vi) 中会递增到 2。看起来那不是你想要做的。
  • 顺便说一句,我使用的是 5.10.1,当我返回 "".$max 时,我得到 2,当我返回 $max 时,我得到 10。

标签: perl lambda closures


【解决方案1】:

主要问题是您将匿名/lambda 子例程声明为sub() {...}。只需使用sub {...}

use strict;
use warnings;

my $i=0;

sub v {
  $i=$i+1;
  return $i;
}

sub make_peak
{
  my $vi=$_[0];
  my $max=-1e35;
  return sub {
    $max = v($vi) if v($vi) > $max;
    return $max; # ??? without the kludge returns empty line
  };
}

my $p=make_peak(11);
my $m=$p->();
print $m;

【讨论】:

  • 这行得通,但我不明白其中的意义。没有原型的 sub 使它更适合作为 lambda 呢?这不就是另一个杂牌吗?
  • 当您将其声明为sub() 时,make_peak 中的@_ 变量将传递给匿名子例程。我不清楚它是如何以 $m 结束的
【解决方案2】:

这似乎是您的 Perl 版本中的一个错误。正在运行

This is perl 5, version 14, subversion 2 (v5.14.2) built for i686-linux-gnu-thread-multi-64int

无论有没有"". 在该行,我都会得到“2”作为输出。

【讨论】:

  • 这对我来说真是个悲伤的消息。我正在运行“这是 perl,为 MSWin32-x86-perlio 构建的 v5.8.6”
  • Perl 5.8.6 已经快九岁了。
  • 是的。我必须忍受它,因为这是安装的,我不能更新它。
猜你喜欢
  • 2013-09-18
  • 2020-04-05
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多