File Coverage

blib/lib/Tie/Scalar/RingBuffer.pm
Criterion Covered Total %
statement 54 59 91.5
branch 21 36 58.3
condition 7 14 50.0
subroutine 11 13 84.6
pod 3 3 100.0
total 96 125 76.8


line stmt bran cond sub pod time code
1             package Tie::Scalar::RingBuffer;
2              
3 1     1   23030 use 5.008;
  1         4  
  1         36  
4 1     1   6 use strict;
  1         3  
  1         35  
5 1     1   5 use warnings;
  1         6  
  1         31  
6 1     1   5 use Carp qw(croak);
  1         2  
  1         850  
7             our $VERSION = '0.04';
8              
9 1 50   1   5 sub _castbool ($) { $_[0] ? 1 : 0 }
10              
11             sub TIESCALAR {
12 8     8   63 my $class = shift;
13 8         14 my $list = shift;
14 8   100     27 my $opts = shift || +{};
15              
16 8 50 33     40 croak "Tie::Scalar::RingBuffer expects a listref" unless @_ == 0 && ref($list) eq 'ARRAY';
17 8 50       19 croak "Tie::Scalar::RingBuffer expects a hashref of options" unless ref($opts) eq 'HASH';
18              
19             # validate options
20 8         28 for (keys %$opts){
21 5 50       30 /^(?:start_offset|increment|random)$/ or croak "Unrecognized option '$_'";
22             }
23              
24 8 50 66     31 if (exists($opts->{'increment'}) && exists($opts->{'random'})){
25 0         0 croak "options 'increment' and 'random' are mutually exclusive"
26             }
27              
28             # set defaults
29 8         52 my $self = bless +{ _list => $list,
30             _ix => 0,
31             _last_ix => 0,
32             _random => 0,
33             _debug => 0,
34             _incr => 1}, $class;
35              
36             # apply options
37 8 100       18 if (exists $opts->{'random'}){
38 1         5 $self->{_random} = _castbool ($opts->{'random'});
39 1         2 $self->start_offset(int rand @{$self->{_list}});
  1         5  
40             }
41 8 100       23 $self->start_offset ($opts->{'start_offset'}) if exists $opts->{'start_offset'};
42 8 100       22 $self->increment ($opts->{'increment'}) if exists $opts->{'increment'};
43              
44 8         27 $self
45             }
46              
47             sub FETCH
48             {
49 83     83   324 my $self = shift;
50 83 50       181 print ("FETCH(ix=",$self->{_ix},")\n") if $self->{_debug};
51 83         142 my ($list,$ix) = ($self->{_list}, $self->{_ix});
52 83 100       188 $self->{_ix} = $self->{_random} ? (rand @$list)
53             : ($ix + $self->{_incr}) % @$list;
54 83         97 $self->{_last_ix} = $ix;
55 83         242 $list->[$ix];
56             }
57              
58             sub redo ()
59             {
60 0     0 1 0 my $self = shift;
61 0 0       0 croak "redo expects an object" unless UNIVERSAL::isa($self, __PACKAGE__);
62 0         0 $self->{_list}->[$self->{_last_ix}]
63             }
64              
65             sub STORE
66             {
67 3     3   6 my $self = shift;
68 3 50       8 print("STORE(_last_ix=",$self->{_last_ix},")\n") if $self->{_debug};
69 3         13 $self->{_list}->[$self->{_last_ix}] = shift;
70             }
71              
72 7     7   1917 sub UNTIE { }
73 0     0   0 sub DESTROY { }
74              
75             sub start_offset {
76 3     3 1 5 my $self = shift;
77 3 50       12 croak "start_offset() expects an object" unless UNIVERSAL::isa($self,__PACKAGE__);
78              
79 3 50       7 if (@_){
80 3         3 my $start_offset = shift;
81 3 50 33     48 croak "start_offset() expects a numeric offset" unless defined($start_offset) && $start_offset =~ /^[+-]?\d+$/;
82 3         4 $self->{_ix} = ($start_offset % scalar @{$self->{_list}});
  3         9  
83             }
84 3         7 $self->{_ix};
85             }
86              
87             sub increment {
88 2     2 1 6 my $self = shift;
89 2 50       11 croak "increment() expects an object" unless UNIVERSAL::isa($self,__PACKAGE__);
90 2 50       7 if(@_){
91 2         3 my $incr = shift;
92 2 50 33     24 croak "increment() expects an integer" unless defined($incr) && $incr =~ /^[+-]?\d+$/;
93 2         6 $self->{_incr} = $incr;
94             }
95 2         3 $self->{_incr};
96             }
97              
98              
99             1;
100             __END__