perl – 如何使用嵌套闭包作为List :: Util :: reduce的第一个参数?

注意:这个问题中的闭包只是一个方便的例子;我实际使用的那个比这复杂得多. IOW,请忽略这个关闭的细节;重要的是AFAICT,它指的是父范围内的词汇变量.

我想重新定义下面的子foo,以便调用List :: Util :: reduce的第一个参数替换为对嵌套闭包的引用.

use strict;
use warnings FATAL => 'all';
use List::Util;

sub foo {
  my ( $x,$y ) = @_;
  return List::Util::reduce { $y->[ $b ]{ $x } ? $a + ( 1 << $b ) : $a } 0,0 .. $#$y;
}

我的第一次尝试是这样的:

sub foo {
  my ( $x,$y ) = @_;
  sub z {
    our ( $a,$b );
    return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a;
  }
  return List::Util::reduce \&z,0 .. $#{ $y };
}

…但是这会导致警告说变量“$y”不会保持共享状态.

我以前见过这种错误,我唯一知道的方法是用分配给变量的匿名子替换嵌套的子定义.因此,我尝试了这个:

sub foo {
  my ( $x,$y ) = @_;
  my $z = sub {
    our ( $a,$b );
    return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a;
  };
  return List::Util::reduce( $z,0 .. $#{ $y } );
}

现在错误说,对于List :: Util :: reduce,arg 1的类型必须是block或sub {}(不是私有变量).

这个我真的不明白.为什么将subref作为第一个参数传递给reduce不被支持

PS:以下工作:

sub foo {
  my ( $x,$b );
    return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a;
  };
  return List::Util::reduce { $z->( $a,$b ) } 0,0 .. $#{ $y };
}

…但我真的想知道(a)使用subref作为List :: Util :: reduce的第一个参数有什么问题(例如,是否存在支持这种变体的技术障碍?); (b)是否有更直接的方法(比{$z->;($a,$b)})传递给List :: Util :: reduce一个嵌套的闭包?

解决方法

reduce有& @的原型.这意味着调用必须使用以下语法之一:

reduce BLOCK LIST
reduce sub BLOCK,LIST  # The first form is short for this.
reduce \&NAME,LIST
reduce \&$NAME,LIST    # Same as third form,but via reference (short form)
reduce \&BLOCK,but via reference (long form)

您可以使用以下任何等效语句:

return reduce { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a } 0,0 .. $#$y;

 

# Long way of writing the first.
return reduce(sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a },0 .. $#$y);

 

my $z = sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a };
return reduce(\&$z,0 .. $#$y);

您还可以选择覆盖原型.

my $z = sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a };
return &reduce($z,0 .. $#$y);

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...