为什么';不能让高阶Perl工作吗?

为什么';不能让高阶Perl工作吗?,perl,iterator,Perl,Iterator,我正在尝试让这个迭代器代码从HOP开始工作: # code from HOP p.156 sub make_rand { my $seed = shift || (time & 0x7fff); return Iterator { $seed = (29*$seed+11111) & 0x7fff; return $seed; } } # code adapted from HOP p.157 my $rng = make_rand(1)

我正在尝试让这个迭代器代码从HOP开始工作:

# code from HOP p.156
sub make_rand {
my $seed = shift || (time & 0x7fff);
return Iterator 
    {   $seed = (29*$seed+11111) & 0x7fff;
        return $seed; 
    }
}

# code adapted from HOP p.157
my $rng = make_rand(1);
while (<>) {    
#   my $random = NEXTVAL($rng); # original code from HOP, adapted as next line
    my $random = $rng->();  # this treats $rng as a number, not as a ref to a sub
    print "\nrandom=$random";
}
#来自HOP p.156的代码
分包商{
我的$seed=shift | |(time&0x7fff);
返回迭代器
{$seed=(29*$seed+11111)&0x7fff;
返回$seed;
}
}
#代码改编自HOP第157页
my$rng=制造兰特(1);
而{
#my$random=NEXTVAL($rng)#来自HOP的原始代码,改编为下一行
my$random=$rng->()#这将$rng视为一个数字,而不是子对象的引用
打印“\n随机=$random”;
}
如前所述,$rng作为一个数字返回,而不是作为迭代器的引用返回,因此当我尝试取消引用它时,它在下一行的最后一行中给出了一个错误

我应该为NEXTVAL使用不同的表单吗

如果我单独定义子迭代器,程序运行良好,例如:

sub make_rand {
  my $seed = shift || (time & 0x7fff);
  return Iterator($seed);
}
sub Iterator {
    my $seed = shift;
    $seed = (29*$seed+11111) & 0x7fff;
    return $seed;
  }

#main
my $random = make_rand(1);
print "\nat42: random=$random";

while (<>) 
{   $random = Iterator($random);
    print "\nat48: random=$random";
}
子品牌{
我的$seed=shift | |(time&0x7fff);
返回迭代器($seed);
}
子迭代器{
我的$seed=shift;
$seed=(29*$seed+11111)和0x7fff;
返回$seed;
}
#主要
my$random=制造品牌(1);
打印“\nat42:random=$random”;
而()
{$random=迭代器($random);
打印“\nat48:random=$random”;
}

您需要随附的文件
Iterator_Utils.pm
,这样您就可以
使用Iterator_Utils qw(Iterator)
,或者在调用
Iterator
之前,将
Iterator
子例程的定义插入您自己的代码中:

sub Iterator (&) { return $_[0] }
或者,由于这只是允许您编写
Interator{…}
来声明匿名子例程而不使用
sub
关键字的一种方法,因此您可以将
Iterator
替换为
sub
,这样就可以了


[1] 这是使用原型声明子例程的众多缺点之一。因为原型告诉解析器如何解释原型子例程调用,所以原型声明必须早于调用本身出现在文件中。

对于那些好奇为什么
return Iterator{…}
在没有预先声明
Iterator
的情况下编译的人来说:间接对象符号再次出现
perl-MO=constructe-e'Foo{return bar}
显示
迭代器
被视为方法调用(尽管我不知道块如何调用方法)。是的,谢谢!简单地用“sub”替换“Iterator”就可以了!查看第122页对Iterator_Utils.pm的描述肯定不会给出(至少对像我这样的疯子来说)正在发生什么的暗示。我看不出“语法糖”有什么意义,它不必要地使代码复杂化。它实际上是语义糖
Iterator
标记返回的匿名sub将用作迭代器,而
sub
没有此类含义。