The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Array::Tour - Base class for Array Tours.

SYNOPSIS

  #
  # For a new package.  Add extra methods and internal attributes afterwards.
  #
  package Array::Tour::NewTypeOfTour
  use base qw(Array::Tour);
  
  # (Code goes here).

or

  #
  # Make use of the constants in the package. 
  #
  use Array::Tour qw(:directions);
  use Array::Tour qw(:status);

or

  #
  # Use Array::Tour for its default 'typewriter' tour of the array.
  #
  use Array::Tour;
  
  my $by_row = Array::Tour->new(dimensions => [24, 80, 1]);
  

PREREQUISITES

Perl 5.8 or later. This is the version of perl under which this module was developed.

DESCRIPTION

Array::Tour is a base class for iterators that traverse the cells of an array. This class should provide most of the methods needed for any type of tour, whether it needs to visit each cell or not, and whether the tour needs to be a continuous path or not.

The iterator provides coordinates and directions. It does not define the array. This leaves the user of the tour object free to define the form of the array or the data structure behind it without restrictions from the tour object.

By itself without any subclassing or options, the Array::Tour class traverses a simple left-to-right, top-to-bottom typewriter path. There are options to change the direction or rotation of the path.

Tour Object Methods

new([<attribute> => value, ...])

Creates the object with its attributes.

With the exception of dimensions and offest, attributes are set using the internal method _set(). This means that subclasses should not override new(), but instead provide their own _set() method to handle their own attributes.

In addition to dimensions and offeset, new() also creates internal attributes that may be used by subclasses. See the Attributes section for more details.

reset()

  $tour->reset([<attribute> => value, ...])

Reset the object by returning its internal state to its original form. Optionally change some of the characteristics using the same parameters found in the new() method.

has_next()

Returns 1 if there is more to the tour, 0 if finished.

get_dimensions()

Returns an array of the dimensions.

direction()

Returns the current direction as found in the :directions EXPORT tag.

opposite_direction()

Return the direction opposite from the current direction.

say_direction()

Return the name in English of the current direction.

direction_name()

Return the name in English of the direction passed in.

   print $tour->direction_name(NorthWest), " is ", NorthWest, "\n";

get_position()

Return a reference to an array of coordinates of the current position.

    @absolute_pos = @{$self->get_position()};

get_offset()

Return a reference to an array of offsets to be added to the current position.

    @offset = @{$self->get_offset()};

adjusted_position()

Return a reference to an array of coordinates that are created from the position plus the offset. Used by the next() method.

    @current_pos = @{$self->adjusted_position()};

next()

Returns an array reference to the next coordinates to use. Returns undef if the iterator is finished.

    my $ctr = 1;
    my $tour = Array::Tour->new(dimensions => 64);

    while (my $cref = $tour->next())
    {
        my($x_coord, $y_coord, $z_coord) = @{$cref};
        $grid[$y_coord, $x_coord] = isprime($ctr++);
    }

The above example would look like a completed Sieve of Eratothenes in the array @grid.

get_array()

Return a reference to the internally generated array.

    $arrayref = $self->get_array()

describe()

Returns as a hash the attributes of the tour object. The hash may be used to create a new object.

Internal Tour Object Methods

_set_dimensions()

    my $tour = Array::Tour->new(dimensions => [12, 16]);

This works identically as

    my $tour = Array::Tour->new(dimensions => [12, 16, 1]);

If the grid is going to be square, a single integer is sufficient:

    my $tour = Array::Tour->new(dimensions => 16);

In both cases, the new() member funcntion calls _set_dimensions() and sets the dimensions attribute with a reference to a three dimensional array. The third dimension is set to 1 if no value is given for it.

_set_offset()

The new() member funcntion calls _set_offset() and sets the offset attribute with a reference to an array of coordinates. This method matches the size of the offset array to the size of dimensions, so _set_dimensions() must be called beforhand.

_move_to()

        $position = $self->_move_to($direction);        # [$c, $r, $l]

Return a new position depending upon the direction taken. This does not set a new position.

_make_array()

        $self->_make_array();
or
        $self->_make_array($value);

Make an internal array for reference purposes. If no value to set the array cels with is passed in, the array cells are set to zero by default.

_set()

$self->_set(%attributes);

Take the parameters provided to new() and use them to set the attributes of the touring object.

_uses_array()

Returns 0 or 1 depending upon whether there's an internal array to return.

Methods expected to be provided by the derived class.

The methods that will have to be written specifically for the individual tour of the derived classe will will likely be:

next()

_set()

_uses_array()

Attributes

Array::Tour keeps track of its state through internal attributes that are sufficient for its purposes. Derived classes may alter these for their own purposes and will likely need to add attributes of their own.

dimensions

Default value: [1, 1, 1]. Set in the method new() using the dimensions key, which in turn sets it through the set_dimensions() method.

  my $spath1 = Array::Tour->new(dimensions => [16, 16, 1]);
or
  my $spath1 = Array::Tour->new(dimensions => [16, 16]);

The dimensions attribute represents a three-dimensional array, defined by rows, columns, and levels. If you are interested only in a two-dimensional array, you don't need to specify the third dimension -- it will be added on for you.

In fact the dimensions attribute is so forgiving that if you are only interested in a simple square array, this will be sufficient:

  my $spath1 = Array::Tour->new(dimensions => 16);

The attribute will detect the single dimension, duplicate it, and add the third dimension of 1. You will have the same dimensions as the previous examples.

offset

Default value: [0, 0, 0]. Set in the method new() using the offset key, which in turn sets it through the _set_offset() method.

Sets the coordinate of the upper left corner of the tour array. Calls to adjusted_position() (which in turn is called by the next() method) will return the position adjusted by the value in offset.

start

Default value: [0, 0, 0]. The starting position of the tour. Set automatically in this class.

position

The current position of the iterator in the array.

odometer

Starting value: 0. The number of cells visited thus far.

tourlength

Default value: number of cells in the array. The total number of cells to visit. This is sometimes used to determine the endpoint of the tour.

tourstatus

Initially set to START. The remaining _tourstatus values (found with the export tag :status) are TOURING and STOP.

array

default value: undef. A reference to an internal array. Some sub-classes need an internal array for bookkeeping purposes. This is where it will go. The method _make_array() will create an internal array for a sub-class if it is needed.

Current Tours

This, the base class, performs a typewriter left-to-right tour of the array. If the array has a third dimension, it will go to the next level after completing the tour of the rows of the current level.

The subclasses that come with this package are:

Spiral

Serpentine

RandomWalk

There may be other tours under development. See the Changes file for more information.

EXPORT

The :directions tag will let you use the constants that indicate direction. They are the directions North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest, Ceiling, Floor, and SetPosition, which indicates a directionless change in position.

The :status tag has the values for the running state of the iterator.

See Also

Array::Iterator

AUTHOR

John M. Gamble may be found at <jgamble@cpan.org>