File Coverage

blib/lib/Lab/Moose/Instrument/Cache.pm
Criterion Covered Total %
statement 65 65 100.0
branch 20 20 100.0
condition n/a
subroutine 106 360 29.4
pod 1 1 100.0
total 192 446 43.0


line stmt bran cond sub pod time code
1             package Lab::Moose::Instrument::Cache;
2             $Lab::Moose::Instrument::Cache::VERSION = '3.881';
3             #ABSTRACT: Device caching functionality in Moose::Instrument drivers
4              
5 18     18   14868 use v5.20;
  18         69  
6              
7              
8 18     18   179 use Moose;
  18         43  
  18         127  
9 18     18   112140 use MooseX::Params::Validate;
  18         67  
  18         186  
10              
11             Moose::Exporter->setup_import_methods( with_meta => ['cache'] );
12              
13 18     18   8151 use namespace::autoclean;
  18         76  
  18         304  
14              
15             sub cache {
16 210     210 1 45831 my ( $meta, $name, %options ) = @_;
17              
18 210         651 my @options = %options;
19 210         1739 validated_hash(
20             \@options,
21             getter => { isa => 'Str' },
22             isa => { optional => 1, default => 'Any' },
23             index_arg => { isa => 'Str', optional => 1 },
24             );
25              
26 210         49232 my $getter = $options{getter};
27 210         448 my $isa = $options{isa};
28 210         370 my $index_arg = $options{index_arg};
29 210         423 my $have_index_arg = defined $index_arg;
30 210         490 my $function = "cached_$name";
31 210         531 my $attribute = "cached_${name}_attribute";
32 210         513 my $builder = "cached_${name}_builder";
33 210         426 my $clearer = "clear_cached_$name";
34 210         440 my $predicate = "has_cached_$name";
35              
36             # Creat builder method for the entry. The user can override
37             # (method modifier) this in an instrument driver to add additional
38             # arguments to the getter.
39             $meta->add_method(
40             $builder => sub {
41 29     29   54 my $self = shift;
        0      
        0      
        0      
        0      
        9      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        20      
        20      
        0      
        0      
        0      
        0      
        0      
        0      
        20      
        0      
        0      
        16      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        9      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        16      
        0      
        16      
        0      
        20      
        20      
        20      
        20      
        20      
        8      
        0      
        1      
        1      
        0      
        1      
        0      
        0      
        0      
        1      
        1      
        1      
        20      
        20      
        20      
        0      
        0      
        1      
        1      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        16      
        1      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        8      
        8      
        8      
        8      
        8      
        8      
42 29 100       72 if ($have_index_arg) {
43 1         7 my ($index) = validated_list(
44             \@_,
45             $index_arg => { isa => 'Int' }
46             );
47 1         374 return $self->$getter( $index_arg => $index );
48             }
49 28         194 return $self->$getter();
50             }
51 210         1496 );
52              
53             $meta->add_attribute(
54             $attribute => (
55             is => 'rw',
56             init_arg => undef,
57             isa => 'ArrayRef',
58 173     173   11107 default => sub { [] },
59             )
60 210         13341 );
61              
62             $meta->add_method(
63             $function => sub {
64 1730     1730   9413 my $self = shift;
        18      
        168      
        18      
        22      
        186      
        164      
        0      
        4      
        0      
        0      
        146      
        0      
        254      
        254      
        4      
        146      
        0      
        146      
        0      
        0      
        254      
        146      
        68      
        223      
        0      
        146      
        0      
        0      
        4      
        4      
        0      
        186      
        150      
        0      
        0      
        0      
        68      
        0      
        146      
        223      
        0      
        223      
        0      
        254      
        254      
        254      
        254      
        254      
        547      
        0      
        275      
        275      
        149      
        492      
        149      
        149      
        0      
        275      
        275      
        492      
        254      
        254      
        254      
        18      
        0      
        1073      
        1073      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        241      
        1073      
        0      
        150      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        4      
65 1730         6615 my $array = $self->$attribute();
66              
67 1730 100       11339 if ($have_index_arg) {
68 7         42 my ( $index, $value ) = validated_list(
69             \@_,
70             $index_arg => { isa => 'Int' },
71             value => { optional => 1 },
72             );
73 5 100       1134 if ( defined $value ) {
74              
75             # Store entry.
76 2         8 return $array->[$index] = $value;
77             }
78              
79             # Query cache.
80 3 100       12 if ( defined $array->[$index] ) {
81 2         27 return $array->[$index];
82             }
83 1         7 return $array->[$index]
84             = $self->$builder( $index_arg => $index );
85             }
86              
87             # No vector index argument. Behave like usual Moose attribute.
88 1723 100       4138 if ( @_ == 0 ) {
89              
90             # Query cache.
91 1062 100       2492 if ( defined $array->[0] ) {
92 1033         4340 return $array->[0];
93             }
94 29         168 $array->[0] = $self->$builder();
95 29         241 return $array->[0];
96             }
97              
98             # Store entry.
99 661         2897 my ($value) = pos_validated_list( \@_, { isa => $isa } );
100 660         53339 return $array->[0] = $value;
101             }
102 210         369615 );
103              
104             $meta->add_method(
105             $clearer => sub {
106 2     2   5 my $self = shift;
        2      
        2      
        2      
        2      
        2      
        2      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
107 2         4 my $index;
108 2 100       6 if ($have_index_arg) {
109              
110             # If no index is given, clear them all!
111 1         6 ($index) = validated_list(
112             \@_,
113             $index_arg => { isa => 'Int', optional => 1 },
114             );
115             }
116 2 100       385 if ( defined $index ) {
117 1         15 $self->$attribute->[$index] = undef;
118             }
119             else {
120 1         4 $self->$attribute( [] );
121             }
122             }
123 210         10236 );
124              
125             $meta->add_method(
126             $predicate => sub {
127 4     4   13 my $self = shift;
        4      
        4      
        4      
        4      
        4      
        4      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
        0      
128 4         7 my $index = 0;
129 4 100       11 if ($have_index_arg) {
130 2         21 ($index) = validated_list(
131             \@_,
132             $index_arg => { isa => 'Int' }
133             );
134             }
135              
136 4         538 my $array = $self->$attribute();
137 4 100       26 if ( defined $array->[$index] ) {
138 2         13 return 1;
139             }
140 2         11 return;
141             }
142 210         8880 );
143             }
144              
145             1;
146              
147             __END__
148              
149             =pod
150              
151             =encoding UTF-8
152              
153             =head1 NAME
154              
155             Lab::Moose::Instrument::Cache - Device caching functionality in Moose::Instrument drivers
156              
157             =head1 VERSION
158              
159             version 3.881
160              
161             =head1 SYNOPSIS
162              
163             in your driver:
164              
165             use Lab::Moose::Instrument::Cache;
166              
167             cache foobar => (getter => 'get_foobar');
168              
169             sub get_foobar {
170             my $self = shift;
171            
172             return $self->cached_foobar(
173             $self->query(command => ...));
174             }
175              
176             sub set_foobar {
177             my ($self, $value) = @_;
178             $self->write(command => ...);
179             $self->cached_foobar($value);
180             }
181              
182             =head1 DESCRIPTION
183              
184             This package exports a new Moose keyword: B<cache>.
185              
186             Calling C<< cache key => (getter => $getter, isa => $type) >> generates the
187             following functions:
188              
189             =over
190              
191             =item C<cached_key> (accessor)
192              
193             Calling C<< $instr->cached_key() >> will return the last stored value from the
194             cache. If the cache entry is empty, use the C<$getter> method.
195              
196             To update the cache entry, call C<< $instr->cached_key($value) >>.
197              
198             =item C<has_cached_key> (predicate)
199              
200             Return true if the cache entry holds a value (which is not undef).
201              
202             =item C<clear_cached_key> (clearer)
203              
204             Clear the value of the cache entry.
205              
206             =item C<cached_key_builder> (builder)
207              
208             Called by C<cached_key> if the entry is cleared. This will call the C<$getter>
209             method. Can be overriden by 'around' method modifier if the C<$getter> needs
210             special extra arguments.
211              
212             =back
213              
214             The C<isa> argument is optional.
215              
216             =head2 Array cache
217              
218             Some methods take an additional parameter (e.g. channel number). For this case
219             you can give the C<index_arg> argument to the cache keyword:
220              
221             cache foobar => (isa => 'Num', getter => 'get_foobar', index_arg => 'channel');
222              
223             # Get value from cache.
224             my $value = $instr->cached_foobar(channel => 1);
225            
226             # Store value.
227             $instr->cached_foobar(channel => 2, value => 1.234);
228            
229             # Clear single entry.
230             $instr->clear_cached_foobar(channel => 3);
231            
232             # Clear them all.
233             $instr->clear_cached_foobar();
234            
235             # Check for cache value
236             if ($instr->has_cached_foobar(channel => 1)) {...}
237              
238             =head1 COPYRIGHT AND LICENSE
239              
240             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
241              
242             Copyright 2016 Simon Reinhardt
243             2017 Andreas K. Huettel, Simon Reinhardt
244             2018 Simon Reinhardt
245             2020 Andreas K. Huettel
246              
247              
248             This is free software; you can redistribute it and/or modify it under
249             the same terms as the Perl 5 programming language system itself.
250              
251             =cut