This is basically a wrap-around array model with bounds checking; however, an address of an element can never be out of bounds, since the model folds all indices back into the model's valid address space.
# ------------------------------------------------------- # Ring.pm : memory ring model # Author : Velaki (velaki@aol.com) # Date : 09 July 2004 # Version : 1.0 # History : # # 1.0 09 July 2004 -- added init routines <Auth> # 0.2 09 July 2004 -- converted set/get to cell <Auth> # 0.1 08 July 2004 -- initial version <Auth> # # ------------------------------------------------------- package Ring; require Exporter; @ISA = qw/Exporter/; @EXPORT = qw//; @EXPORT_OK = qw//; $VERSION = 1.0; use strict; my $DEFAULT_SIZE = 10; # Default ring size for memory ring. # ------------------------------------------------------- # Name : new # Desc : create a new memory ring # # Input : size to make memory ring, or none # Output: new memory ring segment # sub new { my $this = shift; my $class = ref($this) || $this; my $size = shift || $DEFAULT_SIZE; my $self = { SIZE => $size, RING => [] }; bless $self, $class; $self->init; return $self; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : init # Desc : blank the ring memory # # Input : none # Output: none # sub init { my $self = shift; $self->cell($_) = 0 for (0 .. $self->size); } # ------------------------------------------------------- # ------------------------------------------------------- # Name : size # Desc : get the size of the ring # # Input : none # Output: the size of the ring # sub size { my $self = shift; return $self->{SIZE}; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : cell # Desc : get or set the value of a ring cell # # Input : address to be set/retrieved # Output: the current value at the address # sub cell : lvalue { # making it an lvalue means # we can set it during # retrival, e.g. # $c->cell(3) = 10; # print $c->cell(3); # prints: 10 my $self = shift; my $addr = shift; # the address is normalized before being used $self->{RING}[$self->naddr($addr)]; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : naddr # Desc : Normalize ring address to a positive number. # # Input : signed integer address # Output: unsigned address guaranteed to fit in ring # sub naddr { my $self = shift; my $addr = shift; return $addr % $self->size; } # ------------------------------------------------------- 1; # end of module

Replies are listed 'Best First'.
Re: Ring Memory
by rjray (Chaplain) on Jul 30, 2004 at 23:07 UTC

    This might be more useful as a tied-array implementation, which would allow people to use it directly as an array. Have a look at perltie.

    --rjray

      I hate ties but they are a necessary evil in a language where the basic data types aren't objects. So a tied version is a good idea but please preserve the OO interface too, there's no reason not to have both.

        Yeah, I originally started to write it as a tie, but wound up making it OO because I was going to make it N-dimensional, plus many of my users don't like/are confused by ties, but objects they love. In the end, the module stayed an array, so I'll add the tie interface for the 2.0 version, but I'll leave the OO portion, simply because the tie will be a wrapper around it. This way I can have access to the component functions from an inspection standpoint, if necessary.

        Thanks for the comments!

        "Perl. There is no substitute."