File Coverage

blib/lib/MARC/Field.pm
Criterion Covered Total %
statement 153 168 91.0
branch 41 52 78.8
condition 8 9 88.8
subroutine 22 24 91.6
pod 16 16 100.0
total 240 269 89.2


line stmt bran cond sub pod time code
1             package MARC::Field;
2              
3 30     30   13912 use strict;
  30         46  
  30         1121  
4 30     30   139 use integer;
  30         53  
  30         120  
5 30     30   527 use Carp;
  30         40  
  30         2225  
6              
7 30     30   147 use constant SUBFIELD_INDICATOR => "\x1F";
  30         40  
  30         1974  
8 30     30   146 use constant END_OF_FIELD => "\x1E";
  30         39  
  30         1329  
9              
10 30     30   138 use vars qw( $ERROR );
  30         47  
  30         45609  
11              
12             =head1 NAME
13              
14             MARC::Field - Perl extension for handling MARC fields
15              
16             =head1 SYNOPSIS
17              
18             use MARC::Field;
19              
20             my $field = MARC::Field->new( 245, '1', '0',
21             'a' => 'Raccoons and ripe corn / ',
22             'c' => 'Jim Arnosky.'
23             );
24             $field->add_subfields( "a", "1st ed." );
25              
26             =head1 DESCRIPTION
27              
28             Defines MARC fields for use in the MARC::Record module. I suppose
29             you could use them on their own, but that wouldn't be very interesting.
30              
31             =head1 EXPORT
32              
33             None by default. Any errors are stored in C<$MARC::Field::ERROR>, which
34             C<$MARC::Record> usually bubbles up to C<$MARC::Record::ERROR>.
35              
36             =head1 METHODS
37              
38             =head2 new()
39              
40             The constructor, which will return a MARC::Field object. Typically you will
41             pass in the tag number, indicator 1, indicator 2, and then a list of any
42             subfield/data pairs. For example:
43              
44             my $field = MARC::Field->new(
45             245, '1', '0',
46             'a' => 'Raccoons and ripe corn / ',
47             'c' => 'Jim Arnosky.'
48             );
49              
50             Or if you want to add a field < 010 that does not have indicators.
51              
52             my $field = MARC::Field->new( '001', ' 14919759' );
53              
54             =cut
55              
56             sub new {
57 4442     4442 1 14139 my $class = shift;
58 4442         3965 $class = $class;
59              
60             ## MARC spec indicates that tags can have alphabetical
61             ## characters in them! If they do appear we assume that
62             ## they have indicators like tags > 010
63 4442         5801 my $tagno = shift;
64 4442 100       13699 ($tagno =~ /^[0-9A-Za-z]{3}$/)
65             or croak( "Tag \"$tagno\" is not a valid tag." );
66 4440   100     17899 my $is_control = (($tagno =~ /^\d+$/) && ($tagno < 10));
67              
68 4440         17770 my $self = bless {
69             _tag => $tagno,
70             _warnings => [],
71             _is_control_field => $is_control,
72             }, $class;
73              
74 4440 100       7107 if ( $is_control ) {
75 796         1976 $self->{_data} = shift;
76             } else {
77 3644         4765 for my $indcode ( qw( _ind1 _ind2 ) ) {
78 7288         9836 my $indicator = shift;
79 7288 100       18004 if ( $indicator !~ /^[0-9A-Za-z ]$/ ) {
80 34 100       93 $self->_warn( "Invalid indicator \"$indicator\" forced to blank" ) unless ($indicator eq "");
81 34         42 $indicator = " ";
82             }
83 7288         17204 $self->{$indcode} = $indicator;
84             } # for
85              
86 3644 50       7481 (@_ >= 2)
87             or croak( "Field $tagno must have at least one subfield" );
88              
89             # Normally, we go thru add_subfields(), but internally we can cheat
90 3644         11618 $self->{_subfields} = [@_];
91             }
92              
93 4440         13638 return $self;
94             } # new()
95              
96              
97             =head2 tag()
98              
99             Returns the three digit tag for the field.
100              
101             =cut
102              
103             sub tag {
104 1383     1383 1 3742 my $self = shift;
105 1383         6067 return $self->{_tag};
106             }
107              
108             =head2 indicator(indno)
109              
110             Returns the specified indicator. Returns C and sets
111             C<$MARC::Field::ERROR> if the I is not 1 or 2, or if
112             the tag doesn't have indicators.
113              
114             =cut
115              
116             sub indicator($) {
117 88     88 1 743 my $self = shift;
118 88         75 my $indno = shift;
119              
120 88 100       113 $self->_warn( "Fields below 010 do not have indicators" )
121             if $self->is_control_field;
122              
123 88 100       184 if ( $indno == 1 ) {
    50          
124 45         124 return $self->{_ind1};
125             } elsif ( $indno == 2 ) {
126 43         157 return $self->{_ind2};
127             } else {
128 0         0 croak( "Indicator number must be 1 or 2" );
129             }
130             }
131              
132             =head2 is_control_field()
133              
134             Tells whether this field is one of the control tags from 001-009.
135              
136             =cut
137              
138             sub is_control_field {
139 416     416 1 359 my $self = shift;
140 416         966 return $self->{_is_control_field};
141             }
142              
143             =head2 subfield(code)
144              
145             When called in a scalar context returns the text from the first subfield
146             matching the subfield code.
147              
148             my $subfield = $field->subfield( 'a' );
149              
150             Or if you think there might be more than one you can get all of them by
151             calling in a list context:
152              
153             my @subfields = $field->subfield( 'a' );
154              
155             If no matching subfields are found, C is returned in a scalar context
156             and an empty list in a list context.
157              
158             If the tag is less than an 010, C is returned and
159             C<$MARC::Field::ERROR> is set.
160              
161             =cut
162              
163             sub subfield {
164 23     23 1 3321 my $self = shift;
165 23         36 my $code_wanted = shift;
166              
167 23 50       49 croak( "Fields below 010 do not have subfields, use data()" )
168             if $self->is_control_field;
169              
170 23         34 my @data = @{$self->{_subfields}};
  23         83  
171 23         28 my @found;
172 23         79 while ( defined( my $code = shift @data ) ) {
173 53 100       112 if ( $code eq $code_wanted ) {
174 23         78 push( @found, shift @data );
175             } else {
176 30         88 shift @data;
177             }
178             }
179 23 50       49 if ( wantarray() ) { return @found; }
  0         0  
180 23         108 return( $found[0] );
181             }
182              
183             =head2 subfields()
184              
185             Returns all the subfields in the field. What's returned is a list of
186             list refs, where the inner list is a subfield code and the subfield data.
187              
188             For example, this might be the subfields from a 245 field:
189              
190             (
191             [ 'a', 'Perl in a nutshell :' ],
192             [ 'b', 'A desktop quick reference.' ],
193             )
194              
195             =cut
196              
197             sub subfields {
198 1     1 1 2 my $self = shift;
199              
200 1 50       3 $self->_warn( "Fields below 010 do not have subfields" )
201             if $self->is_control_field;
202              
203 1         2 my @list;
204 1         2 my @data = @{$self->{_subfields}};
  1         3  
205 1         3 while ( defined( my $code = shift @data ) ) {
206 1         4 push( @list, [$code, shift @data] );
207             }
208 1         10 return @list;
209             }
210              
211             =head2 data()
212              
213             Returns the data part of the field, if the tag number is less than 10.
214              
215             =cut
216              
217             sub data {
218 6     6 1 6 my $self = shift;
219              
220 6 50       8 croak( "data() is only for tags less than 010, use subfield()" )
221             unless $self->is_control_field;
222              
223 6 50       16 $self->{_data} = $_[0] if @_;
224              
225 6         19 return $self->{_data};
226             }
227              
228             =head2 add_subfields(code,text[,code,text ...])
229              
230             Adds subfields to the end of the subfield list.
231              
232             $field->add_subfields( 'c' => '1985' );
233              
234             Returns the number of subfields added, or C if there was an error.
235              
236             =cut
237              
238             sub add_subfields {
239 1     1 1 2 my $self = shift;
240              
241 1 50       3 croak( "Subfields are only for tags >= 10" )
242             if $self->is_control_field;
243              
244 1         2 push( @{$self->{_subfields}}, @_ );
  1         3  
245 1         4 return @_/2;
246             }
247              
248             =head2 delete_subfields()
249              
250             delete_subfields() will remove *all* of a particular type of subfield from
251             a field.
252              
253             my $count = $field->subfields( 'a' );
254             print "deleted $count subfield 'a' from the field\n";
255              
256             my $count = $field->subfields( 'xz' );
257             print "deleted $count subfields 'x' and 'z' from the field\n";
258            
259             =cut
260              
261             sub delete_subfields {
262 0     0 1 0 my ( $self, $deletes ) = @_;
263 0         0 my @deletes = split //, $deletes;
264 0         0 my @subfields = @{ $self->{_subfields} };
  0         0  
265 0         0 my @new_subfields;
266 0         0 for ( my $i=0; $i<@subfields; $i=$i+2 ) {
267 0         0 push( @new_subfields, $subfields[$i], $subfields[$i+1] )
268 0 0       0 unless grep { $_ eq $subfields[$i] } @deletes;
269             }
270 0         0 $self->{_subfields} = \@new_subfields;
271 0         0 return( (@subfields - @new_subfields)/2 );
272             }
273              
274             =head2 update()
275              
276             Allows you to change the values of the field. You can update indicators
277             and subfields like this:
278              
279             $field->update( ind2 => '4', a => 'The ballad of Abe Lincoln');
280              
281             If you attempt to update a subfield which does not currently exist in the field,
282             then a new subfield will be appended to the field. If you don't like this
283             auto-vivification you must check for the existence of the subfield prior to
284             update.
285              
286             if ( $field->subfield( 'a' ) ) {
287             $field->update( 'a' => 'Cryptonomicon' );
288             }
289              
290             If you want to update a field that has no indicators or subfields (000-009)
291             just call update() with one argument, the string that you would like to
292             set the field to.
293              
294             $field = $record->field( '003' );
295             $field->update('IMchF');
296              
297             Note: when doing subfield updates be aware that C will only
298             update the first occurrence. If you need to do anything more complicated
299             you will probably need to create a new field and use C.
300              
301             Returns the number of items modified.
302              
303             =cut
304              
305             sub update {
306 6     6 1 770 my $self = shift;
307              
308             ## tags 000 - 009 don't have indicators or subfields
309 6 100       13 if ( $self->is_control_field ) {
310 1         3 $self->{_data} = shift;
311 1         3 return(1);
312             }
313              
314             ## otherwise we need to update subfields and indicators
315 5         8 my @data = @{$self->{_subfields}};
  5         16  
316 5         6 my $changes = 0;
317              
318 5         12 while ( @_ ) {
319              
320 9         10 my $arg = shift;
321 9         8 my $val = shift;
322              
323             ## indicator update
324 9 100       16 if ($arg =~ /^ind[12]$/) {
325 1         5 $self->{"_$arg"} = $val;
326 1         3 $changes++;
327             }
328              
329             ## subfield update
330             else {
331 8         7 my $found = 0;
332             ## update existing subfield
333 8         23 for ( my $i=0; $i<@data; $i+=2 ) {
334 17 100       45 if ($data[$i] eq $arg) {
335 5         8 $data[$i+1] = $val;
336 5         4 $found = 1;
337 5         5 $changes++;
338 5         8 last;
339             }
340             } # for
341              
342             ## append new subfield
343 8 100       54 if ( !$found ) {
344 3         4 push( @data, $arg, $val );
345 3         7 $changes++;
346             }
347             }
348              
349             } # while
350              
351             ## synchronize our subfields
352 5         12 $self->{_subfields} = \@data;
353 5         13 return($changes);
354              
355             }
356              
357             =head2 replace_with()
358              
359             Allows you to replace an existing field with a new one. You need to pass
360             C a MARC::Field object to replace the existing field with. For
361             example:
362              
363             $field = $record->field('245');
364             my $new_field = new MARC::Field('245','0','4','The ballad of Abe Lincoln.');
365             $field->replace_with($new_field);
366              
367             Doesn't return a meaningful or reliable value.
368              
369             =cut
370              
371             sub replace_with {
372              
373 1     1 1 492 my ($self,$new) = @_;
374 1 50       13 ref($new) =~ /^MARC::Field$/
375             or croak("Must pass a MARC::Field object");
376              
377 1         9 %$self = %$new;
378              
379             }
380              
381              
382             =head2 as_string( [$subfields] )
383              
384             Returns a string of all subfields run together. A space is added to
385             the result between each subfield. The tag number and subfield
386             character are not included.
387              
388             Subfields appear in the output string in the order in which they
389             occur in the field.
390              
391             If C<$subfields> is specified, then only those subfields will be included.
392              
393             my $field = MARC::Field->new(
394             245, '1', '0',
395             'a' => 'Abraham Lincoln',
396             'h' => '[videorecording] :',
397             'b' => 'preserving the union /',
398             'c' => 'A&E Home Video.'
399             );
400             print $field->as_string( 'abh' ); # Only those three subfields
401             # prints 'Abraham Lincoln [videorecording] : preserving the union /'.
402              
403             Note that subfield h comes before subfield b in the output.
404              
405             =cut
406              
407             sub as_string() {
408 54     54 1 711 my $self = shift;
409 54         66 my $subfields = shift;
410              
411 54 100       121 if ( $self->is_control_field ) {
412 5         42 return $self->{_data};
413             }
414              
415 49         67 my @subs;
416              
417 49         72 my $subs = $self->{_subfields};
418 49         74 my $nfields = @$subs / 2;
419 49         114 for my $i ( 1..$nfields ) {
420 87         117 my $offset = ($i-1)*2;
421 87         162 my $code = $subs->[$offset];
422 87         175 my $text = $subs->[$offset+1];
423 87 100 100     518 push( @subs, $text ) if !$subfields || $code =~ /^[$subfields]$/;
424             } # for
425              
426 49         397 return join( " ", @subs );
427             }
428              
429              
430             =head2 as_formatted()
431              
432             Returns a pretty string for printing in a MARC dump.
433              
434             =cut
435              
436             sub as_formatted() {
437 194     194 1 164 my $self = shift;
438              
439 194         135 my @lines;
440              
441 194 100       221 if ( $self->is_control_field ) {
442 38         129 push( @lines, sprintf( "%03s %s", $self->{_tag}, $self->{_data} ) );
443             } else {
444 156         398 my $hanger = sprintf( "%03s %1.1s%1.1s", $self->{_tag}, $self->{_ind1}, $self->{_ind2} );
445              
446 156         165 my $subs = $self->{_subfields};
447 156         137 my $nfields = @$subs / 2;
448 156         112 my $offset = 0;
449 156         183 for my $i ( 1..$nfields ) {
450 262         588 push( @lines, sprintf( "%-6.6s _%1.1s%s", $hanger, $subs->[$offset++], $subs->[$offset++] ) );
451 262         464 $hanger = "";
452             } # for
453             }
454              
455 194         662 return join( "\n", @lines );
456             }
457              
458              
459             =head2 as_usmarc()
460              
461             Returns a string for putting into a USMARC file. It's really only
462             useful by C.
463              
464             =cut
465              
466             sub as_usmarc() {
467 43     43 1 49 my $self = shift;
468              
469             # Tags < 010 are pretty easy
470 43 100       68 if ( $self->is_control_field ) {
471 6         11 return $self->data . END_OF_FIELD;
472             } else {
473 37         34 my @subs;
474 37         37 my @subdata = @{$self->{_subfields}};
  37         79  
475 37         79 while ( @subdata ) {
476 49         136 push( @subs, join( "", SUBFIELD_INDICATOR, shift @subdata, shift @subdata ) );
477             } # while
478              
479             return
480 37         60 join( "",
481             $self->indicator(1),
482             $self->indicator(2),
483             @subs,
484             END_OF_FIELD,
485             );
486             }
487             }
488              
489             =head2 clone()
490              
491             Makes a copy of the field. Note that this is not just the same as saying
492              
493             my $newfield = $field;
494              
495             since that just makes a copy of the reference. To get a new object, you must
496              
497             my $newfield = $field->clone;
498              
499             Returns a MARC::Field record.
500              
501             =cut
502              
503             sub clone {
504 18     18 1 18 my $self = shift;
505              
506 18         49 my $tagno = $self->{_tag};
507 18   66     94 my $is_control = (($tagno =~ /^\d+$/) && ($tagno < 10));
508              
509 18         61 my $clone =
510             bless {
511             _tag => $tagno,
512             _warnings => [],
513             _is_control_field => $is_control,
514             }, ref($self);
515              
516 18 100       27 if ( $is_control ) {
517 4         12 $clone->{_data} = $self->{_data};
518             } else {
519 14         30 $clone->{_ind1} = $self->{_ind1};
520 14         28 $clone->{_ind2} = $self->{_ind2};
521 14         13 $clone->{_subfields} = [@{$self->{_subfields}}];
  14         51  
522             }
523              
524 18         52 return $clone;
525             }
526              
527             =head2 warnings()
528              
529             Returns the warnings that were created when the record was read.
530             These are things like "Invalid indicators converted to blanks".
531              
532             The warnings are items that you might be interested in, or might
533             not. It depends on how stringently you're checking data. If
534             you're doing some grunt data analysis, you probably don't care.
535              
536             =cut
537              
538             sub warnings() {
539 1836     1836 1 1926 my $self = shift;
540              
541 1836         1680 return @{$self->{_warnings}};
  1836         6007  
542             }
543              
544             # NOTE: _warn is an object method
545             sub _warn($) {
546 6     6   9 my $self = shift;
547              
548 6         7 push( @{$self->{_warnings}}, join( "", @_ ) );
  6         27  
549             }
550              
551             sub _gripe(@) {
552 0     0     $ERROR = join( "", @_ );
553              
554 0           warn $ERROR;
555              
556 0           return;
557             }
558              
559              
560             1;
561              
562             __END__