触发访问时的数组元素计算

时间:2013-01-12 02:37:33

标签: perl

是否有任何Perl API允许我在读取数组元素时执行代码?我在想(或者它可以吗?)Variable::Magic,我该怎么做?最终目标是基本上重新计算任何访问(延迟评估)的元素值,但我不想将grepmapnatatime等函数限制为不可用。

3 个答案:

答案 0 :(得分:3)

CPAN上有几个模块用于延迟数组。 Data::LazyVariable::LazyTie::Array::LazyVariable::Magic

Data :: Lazy和Tie :: Array :: Lazy两者并列。绑定非常慢,比正常数组慢约10倍,比对象慢约3倍。搭售可能会扼杀懒惰的性能优势。

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

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

我建议反过来解决问题。把东西写成一个可以像它喜欢的懒惰的对象。这比绑定更快,更灵活,可能更有特色,更少错误。对于grep,map等,提供overload它,以便它可以用作数组引用。重载不会是懒惰的,但grep和map必须在整个列表中工作,并且领带不会对你有任何帮助。对象可能能够提供更有效的搜索和转换方法。

答案 1 :(得分:0)

懒惰列表是List::Gen的堡垒之一。

答案 2 :(得分: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进行延迟评估。 mapgrepfor等会在行动前对整个列表进行评估,但它们仍然会有效。