Math-Sequence

 view release on metacpan or  search on metacpan

lib/Math/Sequence.pm  view on Meta::CPAN


=back

=head2 METHODS

=over 2

=item new()

The constructor for Math::Sequence objects. Takes two or three arguments.
In the two argument form, the first argument specifies the recursion
definition. It must be either a string to be parsed by a Math::Symbolic
parser or a Math::Symbolic tree. In the two argument version, the
recursion variable (the one which will be recursively replaced by its
predecessor) will be inferred from the function signature. Thus, the formula
must contain exactly one variable. The second argument must be a starting
value. It may either be a constant or a Math::Symbolic tree or a string to be
parsed as such.

The three argument version adds to the two argument version a string indicating
a variable name to be used as the recursion variable. Then, the recursion
formula may contain any number of variables.

=cut

sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;

    my $formula = shift;
    croak "Sequence->new() takes a formula as first argument."
      if not defined $formula;

    my $parsed = $Parser->parse($formula);
    croak "Error parsing formula" if not defined $parsed;

    my $start = shift;
    croak "A starting value must be supplied to Sequence->new() as second\n"
      . "argument."
      if not defined $start;
    $start = $Parser->parse($start);
    croak "Error parsing starting value." if not defined $start;

    my $variable = shift;
    my @sig      = $parsed->signature();

    if ( @sig != 1 and not defined $variable ) {
        croak "Formula must have one variable or a user defined\n"
          . "variable must be supplied.";
    }
    $variable = $sig[0] if not defined $variable;

    my $self = {
        cached        => 1,
        var           => $variable,
        formula       => $parsed,
        current       => 0,
        current_value => $start,
        cache         => [$start],
    };
    return bless $self => $class;
}

=item next()

The next() method returns the next element of the sequence and advances the
iterator by one. This is the prefered method of walking down a sequence's
recursion.

=cut

sub next {
    my $self          = shift;
    my $current_index = $self->{current};
    my $current_value = $self->{current_value};
    my $next_index    = $current_index + 1;

    if ( $self->{cached} and defined $self->{cache}[$next_index] ) {
        $self->{current_value} = $self->{cache}[$next_index];
        $self->{current}       = $next_index;
        return $current_value;
    }

    my $next_value = $self->{formula}->new();
    $next_value->implement( $self->{var} => $current_value );
    $next_value = $next_value->simplify();

    $self->{cache}[$next_index] = $next_value if $self->{cached};
    $self->{current}            = $next_index;
    $self->{current_value}      = $next_value;

    return $current_value;
}

=item cached()

Returns a true value if the sequence is currently being cached, false if it
isn't. By default, new objects have caching enabled. It is suggested that you
only disable caching if space is an issue and you will only walk the sequence
uni-directionally and only once.

cached() can be used to change the caching behaviour. If the first argument is
true, caching will be enabled. If it is false, caching will be disabled.

=cut

sub cached {
    my $self = shift;
    $self->{cached} = shift if @_;
    return $self->{cached};
}

=item current_index()

Returns the index of the current element. That is, the index of the element
that will be returned by the next call to the next() method.

This method also allows (re-)setting the element that will be next returned by
the next() method. In that case, the first argument shoudl be the appropriate
index.

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.795 second using v1.00-cache-2.02-grep-82fe00e-cpan-9e6bc14194b )