使用惰性求值的 perl 脚本说明
explanation of perl script using lazy evaluation
我想了解下面执行perl脚本的每一步都发生了什么,我的意思是,我知道变量、散列、整数数组是什么,但我不知道它们是如何相互作用的这个 powerset 构造使用惰性评估。
我也想知道哪些因素决定了sub powerset(&@)
子程序的进度是哪一步。
例如,我想从第六个子集开始打印,而不是第一个,那么我应该替换哪些变量的值?
use strict;
use warnings;
sub powerset(&@) {
my $callback = shift;
my $bitmask = '';
my $bytes = @_/8;
{
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
$callback->( @_[@indices] );
++vec($bitmask, $_, 8) and last for 0 .. $bytes;
redo if @indices != @_;
}
}
powerset { print "[@_]\n" } 1..21;
my $bytes = @_/8;
:此处 @_
是数组输入参数,因此 @_ = 1..21
并且在标量上下文中计算时,它 return 是数组的长度。所以$bytes = 21/8 = 2.625
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
这里 $#_
是 @_
中的最后一个索引,即 20。因此这将在数组 0..20
上运行 grep。对于数组中的每个元素,检查是否设置了 $bitmask
中的相应位值,如果设置了则保存在 @indices
数组中。
$callback->( @_[@indices] );
:这会使用对应于 $bitmask
中设置的位的索引数组调用回调函数。由于 $bitmask
最初为空,因此在第一次迭代中,@indices
将等于空数组 []
.
++vec($bitmask, $_, 8) and last for 0 .. $bytes;
:从 0..2 开始循环,因为 $bytes == 2.625
它向下舍入到最接近的整数值。对于 0..2
中的每个字节索引值,$bitmask
中的相应字节(现在被视为字节数组)递增。新的字节值是 returned 从 vec
,如果 returned 值是非零的 for 循环退出(由于 and last
部分。但是,如果值字节为 255,++vec($bitmask, $_, 8)
将 return 为 0(字节值环绕为零),for 0..$bytes
for
循环的下一次迭代将执行。
如果 @indices
数组的长度不同于 @_
的长度(即:21),redo if @indices != @_;
再次运行块(第 7-12 行)。
我想了解下面执行perl脚本的每一步都发生了什么,我的意思是,我知道变量、散列、整数数组是什么,但我不知道它们是如何相互作用的这个 powerset 构造使用惰性评估。
我也想知道哪些因素决定了sub powerset(&@)
子程序的进度是哪一步。
例如,我想从第六个子集开始打印,而不是第一个,那么我应该替换哪些变量的值?
use strict;
use warnings;
sub powerset(&@) {
my $callback = shift;
my $bitmask = '';
my $bytes = @_/8;
{
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
$callback->( @_[@indices] );
++vec($bitmask, $_, 8) and last for 0 .. $bytes;
redo if @indices != @_;
}
}
powerset { print "[@_]\n" } 1..21;
my $bytes = @_/8;
:此处@_
是数组输入参数,因此@_ = 1..21
并且在标量上下文中计算时,它 return 是数组的长度。所以$bytes = 21/8 = 2.625
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
这里$#_
是@_
中的最后一个索引,即 20。因此这将在数组0..20
上运行 grep。对于数组中的每个元素,检查是否设置了$bitmask
中的相应位值,如果设置了则保存在@indices
数组中。$callback->( @_[@indices] );
:这会使用对应于$bitmask
中设置的位的索引数组调用回调函数。由于$bitmask
最初为空,因此在第一次迭代中,@indices
将等于空数组[]
.++vec($bitmask, $_, 8) and last for 0 .. $bytes;
:从 0..2 开始循环,因为$bytes == 2.625
它向下舍入到最接近的整数值。对于0..2
中的每个字节索引值,$bitmask
中的相应字节(现在被视为字节数组)递增。新的字节值是 returned 从vec
,如果 returned 值是非零的 for 循环退出(由于and last
部分。但是,如果值字节为 255,++vec($bitmask, $_, 8)
将 return 为 0(字节值环绕为零),for 0..$bytes
for
循环的下一次迭代将执行。
如果 redo if @indices != @_;
再次运行块(第 7-12 行)。
@indices
数组的长度不同于 @_
的长度(即:21),