File Coverage

blib/lib/WebFetch/Data/Record.pm
Criterion Covered Total %
statement 24 90 26.6
branch 0 22 0.0
condition 0 3 0.0
subroutine 8 15 53.3
pod 5 5 100.0
total 37 135 27.4


line stmt bran cond sub pod time code
1             # WebFetch::Data::Record
2             # ABSTRACT: WebFetch Embedding API data record
3             #
4             # Copyright (c) 2009-2022 Ian Kluft. This program is free software; you can
5             # redistribute it and/or modify it under the terms of the GNU General Public
6             # License Version 3. See https://www.gnu.org/licenses/gpl-3.0-standalone.html
7             #
8              
9             # pragmas to silence some warnings from Perl::Critic
10             ## no critic (Modules::RequireExplicitPackage)
11             # This solves a catch-22 where parts of Perl::Critic want both package and use-strict to be first
12 1     1   914 use strict;
  1         3  
  1         30  
13 1     1   6 use warnings;
  1         2  
  1         48  
14 1     1   8 use utf8;
  1         2  
  1         5  
15             ## use critic (Modules::RequireExplicitPackage)
16              
17             package WebFetch::Data::Record;
18             $WebFetch::Data::Record::VERSION = '0.15.8';
19 1     1   60 use strict;
  1         1  
  1         30  
20 1     1   5 use warnings;
  1         2  
  1         46  
21 1     1   5 use base qw( WebFetch );
  1         6  
  1         81  
22              
23             # define exceptions/errors
24             use Exception::Class (
25 1         7 'WebFetch::Data::Record::Exception::AutoloadFailure' => {
26             isa => 'WebFetch::TracedException',
27             alias => 'throw_autoload_fail',
28             description => "AUTOLOAD failed to handle function call",
29             },
30              
31 1     1   6 );
  1         2  
32              
33             # no user-servicable parts beyond this point
34              
35             our $AUTOLOAD;
36              
37             # initialization
38             sub init
39             {
40 0     0 1   my ( $self, $obj, $num, @args ) = @_;
41              
42             # save parameters
43 0           $self->{obj} = $obj;
44 0           $self->{num} = $num;
45 0           $self->{recref} = $self->{obj}{records}[ $self->{num} ];
46              
47             # signal WebFetch that Data subclasses do not provide a fetch function
48 0           $self->{no_fetch} = 1;
49 0           $self->SUPER::init(@args);
50              
51             # make accessor functions
52 0           my $class = ref($self);
53 0           foreach my $field ( @{ $self->{obj}{fields} } ) {
  0            
54 0           $class->mk_field_accessor($field);
55             }
56 0           foreach my $field ( keys %{ $self->{obj}{wk_names} } ) {
  0            
57 0           $class->mk_field_accessor($field);
58             }
59              
60 0           return $self;
61             }
62              
63             # shortcut function to top-level WebFetch object data
64 0     0 1   sub data { my @args = @_; return $args[0]->{obj}; }
  0            
65              
66             # get a field by number
67             sub bynum
68             {
69 0     0 1   my $self = shift;
70 0           my $f = shift;
71              
72 0           WebFetch::debug "bynum $f";
73 0           return $self->{recref}[$f];
74             }
75              
76             # get a field by name
77             sub byname
78             {
79 0     0 1   my $self = shift;
80 0           my $fname = shift;
81 0           my $obj = $self->{obj};
82 0           my $f;
83              
84 0 0         WebFetch::debug "byname " . ( ( defined $fname ) ? $fname : "undef" );
85 0 0         ( defined $fname ) or return;
86 0 0         if ( exists $obj->{findex}{$fname} ) {
87 0           $f = $obj->{findex}{$fname};
88 0           return $self->{recref}[$f];
89             }
90 0           return;
91             }
92              
93             # make field accessor/mutator functions
94             sub mk_field_accessor
95             {
96 0     0 1   my ( $class, @args ) = @_;
97 0           foreach my $name (@args) {
98 0 0         $class->can($name) and next; # skip if function exists!
99              
100             # make a closure which keeps value of $name from this call
101             # keep generic so code can use more than one data type per run
102             ## no critic (TestingAndDebugging::ProhibitNoStrict)
103 1     1   1164 no strict 'refs';
  1         2  
  1         510  
104 0           *{ $class . "::" . $name } = sub {
105 0     0     my $self = shift;
106 0           my $value = shift;
107 0           my $obj = $self->{obj};
108 0           my $recref = $self->{recref};
109 0           my $f;
110 0 0         if ( exists $obj->{findex}{$name} ) {
    0          
111 0           $f = $obj->{findex}{$name};
112 0 0         if ( defined $value ) {
113 0           my $tmp = $recref->[$f];
114 0           $recref->[$f] = $value;
115 0           return $tmp;
116             } else {
117 0           return $recref->[$f];
118             }
119             } elsif ( exists $obj->{wk_names}{$name} ) {
120 0           my $wk = $obj->{wk_names}{$name};
121 0           $f = $obj->{findex}{$wk};
122 0 0         if ( defined $value ) {
123 0           my $tmp = $recref->[$f];
124 0           $recref->[$f] = $value;
125 0           return $tmp;
126             } else {
127 0           return $recref->[$f];
128             }
129             } else {
130 0           return;
131             }
132 0           };
133             }
134 0           return;
135             }
136              
137             # AUTOLOAD function to provide field accessors/mutators
138             ## no critic (ClassHierarchies::ProhibitAutoloading)
139             sub AUTOLOAD
140             {
141 0     0     my ( $self, @args ) = @_;
142 0 0         my $type = ref($self) or throw_autoload_fail "self is not an object";
143              
144 0           my $name = $AUTOLOAD;
145 0           $name =~ s/.*://x; # strip fully-qualified portion, just want function
146              
147             # decline all-caps names - reserved for special Perl functions
148 0 0         ( $name =~ /^[A-Z]+$/x ) and return;
149              
150 0           WebFetch::debug __PACKAGE__ . "::AUTOLOAD $name";
151 0 0 0       if ( ( exists $self->{obj}{findex}{$name} )
152             or ( exists $self->{obj}{wk_names}{$name} ) )
153             {
154 0           $type->mk_field_accessor($name);
155 0           return $self->$name(@args);
156             } else {
157 0           throw_autoload_fail "no such function or field $name";
158             }
159             }
160              
161             1;
162              
163             __END__
164              
165             =pod
166              
167             =encoding UTF-8
168              
169             =head1 NAME
170              
171             WebFetch::Data::Record - WebFetch Embedding API data record
172              
173             =head1 VERSION
174              
175             version 0.15.8
176              
177             =head1 SYNOPSIS
178              
179             C<use WebFetch::Data::Record;>
180              
181             C<WebFetch::Data::Record->mk_field_accessor( $field_name, ... );
182             $value = $obj-E<gt>bynum( $num );
183             $value = $obj->fieldname;
184             $obj->fieldname( $value );
185             >
186              
187             =head1 DESCRIPTION
188              
189             This module provides read-only access to a single record of the WebFetch data.
190              
191             =over 4
192              
193             =item $value = $obj->bynum( $field_num );
194              
195             Returns the value of the field located by the field number provided.
196             The first field is numbered 0.
197              
198             =item $value = $obj->byname( $field_name );
199              
200             Returns the value of the named field.
201              
202             =item $class->mk_field_accessor( $field_name, ... );
203              
204             Creates accessor functions for each field name provided.
205              
206             =item accessor functions
207              
208             Accessor functions are created for field names and
209             well-known names as they are defined.
210              
211             So a field named "title" can be accessed by an object method of the same
212             name, like $obj->title .
213              
214             =back
215              
216             =head1 SEE ALSO
217              
218             L<WebFetch>
219             L<https://github.com/ikluft/WebFetch>
220              
221             =head1 BUGS AND LIMITATIONS
222              
223             Please report bugs via GitHub at L<https://github.com/ikluft/WebFetch/issues>
224              
225             Patches and enhancements may be submitted via a pull request at L<https://github.com/ikluft/WebFetch/pulls>
226              
227             =head1 AUTHOR
228              
229             Ian Kluft <https://github.com/ikluft>
230              
231             =head1 COPYRIGHT AND LICENSE
232              
233             This software is Copyright (c) 1998-2023 by Ian Kluft.
234              
235             This is free software, licensed under:
236              
237             The GNU General Public License, Version 3, June 2007
238              
239             =cut