3

是否有任何 Perl API 可以让我在读取数组元素时执行代码?我在想类似的东西(或者也许可以?)Variable::Magic,我该怎么做?最终目标是本质上重新计算任何访问(延迟评估)的元素值,但我不想将 , 之类的函数限制grepmap不可natatime用。

4

3 回答 3

3

CPAN 上有几个用于惰性数组的模块。 Data::LazyVariable::LazyTie::Array::LazyVariable::Magic

Data::Lazy 和 Tie::Array::Lazy 都打成平手。绑定非常慢,比普通数组慢约 10 倍,比对象慢约 3 倍。捆绑可能会扼杀懒惰的性能优势。

变量::懒惰是不同的。它实际上是在编译时使用 Devel::Declare 魔法将变量替换为一大段代码。不幸的是,它似乎只适用于标量。:-/

变量::魔法是……魔法。它更多地用于注释变量而不是控制它们。

我建议改为反转问题。将事物写成一个可以随心所欲地懒惰的对象。与领带相比,这更快、更灵活、可能更具特色且错误更少。对于 grep、map 等,提供一个重载它以便它可以用作数组 ref。重载不会是懒惰的,但是 grep 和 map 无论如何都必须在整个列表上工作,并且 tie 不会对你有任何好处。并且对象可能能够提供更高效的搜索和变换方法。

于 2013-01-12T09:06:10.883 回答
0

惰性列表是我们List::Gen的强项之一。

于 2013-01-12T15:26:31.180 回答
0

您可能会发现 brian d foy 的这篇文章很有用:http ://www.effectiveperlprogramming.com/blog/300 。特别是这段代码对和(无限)绑定数组进行惰性求值。

use 5.012;

{
package Tie::Array::InfiniteSquares;

    use parent qw(Tie::Array);
    use Carp qw(carp);
    use Config qw(%Config);

    # mandatory methods
    sub TIEARRAY {
        bless {}, $_[0];
        }
    sub FETCH {
        my( $self, $index ) = @_;
        $index ** 2;
        }

    sub FETCHSIZE { 0x7F_FF_FF_FF } # still problems here

    sub STORE     { carp "You can't touch this!" }
    sub STORESIZE { carp "You can't touch this!" }
    sub EXISTS    { 1 }
    sub DELETE    { carp "You can't touch this!" }

}

tie my @array, 'Tie::Array::InfiniteSquares';

while( my( $index, $value ) = each @array )
    {
    say "Item is $value at index $index";
    }

现在假设您的实际数据集不是无限的,那么当您正确构建绑定类时,您可以each进行惰性评估。map, grep,for等会在行动之前评估整个列表,但它们仍然可以工作。

于 2013-01-12T15:53:06.227 回答