Tie::Array::Lazy - Lazy -- but mutable -- arrays.


Tie-Array-Lazy documentation Contained in the Tie-Array-Lazy distribution.

Index


Code Index:

NAME

Top

Tie::Array::Lazy - Lazy -- but mutable -- arrays.

VERSION

Top

$Id: Lazy.pm,v 0.1 2007/05/26 17:54:19 dankogai Exp dankogai $

SYNOPSIS

Top

  use Tie::Array::Lazy;
  # 0..Inf
  tie my @a, 'Tie::Array::Lazy', [], sub{ $_[0]->index };
  print @a[0..9];      # 0123456789
  $a[1] = 'one';
  print @a[0..9];      # 0one23456789
  print "$_\n" for @a; # prints forever

DESCRIPTION

Top

Tie::Array::Lazy implements a lazy array, an array that generates the element on demand. It is a lot like a lazy list but unlike lazy lists seen in many functional languages like Haskell, lazy arrays are mutable so you can assign values to their elements.

The example below explains how it works.

  tie my @a, 'Tie::Array::Lazy', [3,2,1,0], sub{ 1 };
  my @r = splice @a, 1, 2, qw/two one/
  # @r is (2,1);     tied(@a)->array is [3,'two','one',0];
  pop @a;   # 0;     tied(@a)->array is [3,'two','one'];
  shift @a; # 3;     tied(@a)->array is ['two','one'];
  shift @a; # 'two'; tied(@a)->array is ['one'];
  pop @a;   # 'one;  tied(@a)->array is [];
  pop @a;   # 1;     tied(@a)->array is [];
  @a[3] = 3 #        tied(@a)->array is [1,1,1,3];

You can think lazy arrays as arrays that auto-fills.

EXPORT

Top

None.

FUNCTIONS

Top

tie @array, 'Tie::Array::Lazy', *arrayref*, *coderef*

makes @array a lazy array with its initial state with arrayref and element generator code with coderef. Here is an exmaple;

The coderef is a code reference which $_[0] is the Tie::Array::Lazy object itself (tied(@array)) and $_[1] is the index.

In addition to methods that Tie::Array provides, the object has methods below:

array

The reference to the internal array which stores values either generated or assigned.

  # Fibonacci array
  tie my @a, 'Tie::Array::Lazy', 
      [1, 1], 
      sub{ $_[0]->array->[-2] + $_[0]->array->[-1] }

index

Shorthand for scalar @{ $self->array }.

  # 0..Inf
  tie my @a, 'Tie::Array::Lazy', [], sub{ $_[0]->index };

maker

The reference to the code reference to generate the value needed. Whenever the value is needed, Tie::Array::Lazy invokes the code below;

  $self->maker($self, $index);

Using Tie::Array::Lazy as a base class

Like Tie::Array, you can use this module as a base class. See Tie::Array::Lazier for details.

AUTHOR

Top

Dan Kogai, <dankogai at dan.co.jp>

BUGS

Top

Please report any bugs or feature requests to bug-tie-array-lazy at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Tie-Array-Lazy. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc Tie::Array::Lazy

You can also look for information at:

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/Tie-Array-Lazy

* CPAN Ratings

http://cpanratings.perl.org/d/Tie-Array-Lazy

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=Tie-Array-Lazy

* Search CPAN

http://search.cpan.org/dist/Tie-Array-Lazy

ACKNOWLEDGEMENTS

Top

Nick Ing-Simmons for Tie::Array

Matsumoto Yukihiro (Matz) for teasing me into hacking this module.

COPYRIGHT & LICENSE

Top


Tie-Array-Lazy documentation Contained in the Tie-Array-Lazy distribution.
package Tie::Array::Lazy;
use warnings;
use strict;
our $VERSION = sprintf "%d.%02d", q$Revision: 0.1 $ =~ /(\d+)/g;

sub DESTROY { }

sub TIEARRAY($\@\&;@){
    my ( $pkg, $array, $maker ) = splice @_, 0, 3;
    bless { _array => $array, _maker => $maker, @_ }, $pkg;
}

sub array { $_[0]->{_array} }
sub index { scalar @{ $_[0]->array } }
sub maker { $_[0]->{_maker} }

sub EXTEND($$) {
    my ( $self, $size ) = @_;
    my $index = $self->index;
    while ($index <= $size){
        $self->array->[$index] =  $self->maker->($self, $index);
	$index++;
    }
}

sub FETCH($$) {
    my ( $self, $index ) = @_;
    $self->EXTEND($index);
    $self->array->[$index];
}

sub STORE($$$) {
    my ( $self, $index, $value ) = @_;
    $self->EXTEND($index-1);
    $self->array->[$index] = $value;
}

sub STORESIZE($) { }

sub FETCHSIZE($) { scalar @{ $_[0]->array } + 1 }

sub PUSH($@) { push @{ shift->array }, @_ }

sub UNSHIFT($@) { unshift @{ shift->array }, @_ }

sub SHIFT($) {
    $_[0]->index ? shift @{ $_[0]->array } : $_[0]->maker->( $_[0] )
}

sub POP($) {
    $_[0]->index ? pop @{ $_[0]->array } : $_[0]->maker->( $_[0] )
}

sub CLEAR($){ @{$_[0]->array} = () }

sub SPLICE($;$$@){
    my $self = shift;
    return splice @{$self->array} unless @_;
    my $off = shift;
    $self->EXTEND( $off + 1);
    return splice @{$self->array}, $off unless @_;
    my $len = shift;
    return splice @{$self->array}, $off, $len unless @_;
    splice @{$self->array}, $off, $len, @_;
}

1;
__END__