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.880';
3             #ABSTRACT: Device caching functionality in Moose::Instrument drivers
4              
5 18     18   15064 use v5.20;
  18         79  
6              
7              
8 18     18   183 use Moose;
  18         68  
  18         120  
9 18     18   117232 use MooseX::Params::Validate;
  18         59  
  18         152  
10              
11             Moose::Exporter->setup_import_methods( with_meta => ['cache'] );
12              
13 18     18   8534 use namespace::autoclean;
  18         46  
  18         286  
14              
15             sub cache {
16 210     210 1 46252 my ( $meta, $name, %options ) = @_;
17              
18 210         669 my @options = %options;
19 210         1706 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         52175 my $getter = $options{getter};
27 210         512 my $isa = $options{isa};
28 210         388 my $index_arg = $options{index_arg};
29 210         444 my $have_index_arg = defined $index_arg;
30 210         576 my $function = "cached_$name";
31 210         555 my $attribute = "cached_${name}_attribute";
32 210         529 my $builder = "cached_${name}_builder";
33 210         492 my $clearer = "clear_cached_$name";
34 210         449 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   57 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       74 if ($have_index_arg) {
43 1         6 my ($index) = validated_list(
44             \@_,
45             $index_arg => { isa => 'Int' }
46             );
47 1         421 return $self->$getter( $index_arg => $index );
48             }
49 28         177 return $self->$getter();
50             }
51 210         1610 );
52              
53             $meta->add_attribute(
54             $attribute => (
55             is => 'rw',
56             init_arg => undef,
57             isa => 'ArrayRef',
58 173     173   10754 default => sub { [] },
59             )
60 210         14347 );
61              
62             $meta->add_method(
63             $function => sub {
64 1730     1730   9648 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         6893 my $array = $self->$attribute();
66              
67 1730 100       11439 if ($have_index_arg) {
68 7         37 my ( $index, $value ) = validated_list(
69             \@_,
70             $index_arg => { isa => 'Int' },
71             value => { optional => 1 },
72             );
73 5 100       1213 if ( defined $value ) {
74              
75             # Store entry.
76 2         11 return $array->[$index] = $value;
77             }
78              
79             # Query cache.
80 3 100       11 if ( defined $array->[$index] ) {
81 2         17 return $array->[$index];
82             }
83 1         4 return $array->[$index]
84             = $self->$builder( $index_arg => $index );
85             }
86              
87             # No vector index argument. Behave like usual Moose attribute.
88 1723 100       3979 if ( @_ == 0 ) {
89              
90             # Query cache.
91 1062 100       2634 if ( defined $array->[0] ) {
92 1033         4455 return $array->[0];
93             }
94 29         194 $array->[0] = $self->$builder();
95 29         167 return $array->[0];
96             }
97              
98             # Store entry.
99 661         2977 my ($value) = pos_validated_list( \@_, { isa => $isa } );
100 660         53135 return $array->[0] = $value;
101             }
102 210         381507 );
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       8 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       387 if ( defined $index ) {
117 1         6 $self->$attribute->[$index] = undef;
118             }
119             else {
120 1         6 $self->$attribute( [] );
121             }
122             }
123 210         10730 );
124              
125             $meta->add_method(
126             $predicate => sub {
127 4     4   8 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         9 my $index = 0;
129 4 100       11 if ($have_index_arg) {
130 2         9 ($index) = validated_list(
131             \@_,
132             $index_arg => { isa => 'Int' }
133             );
134             }
135              
136 4         541 my $array = $self->$attribute();
137 4 100       30 if ( defined $array->[$index] ) {
138 2         12 return 1;
139             }
140 2         10 return;
141             }
142 210         9395 );
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.880
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