source: trunk/gsdl/perllib/cpan/MARC/Field.pm@ 3430

Last change on this file since 3430 was 3430, checked in by jrm21, 22 years ago

Added MARCPlug, mostly done by David Bainbridge. It needs a configuration file,
which maps MARC fields into metadata, which is in gsdlhome/etc/marctodc.txt

  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1package MARC::Field;
2
3use strict;
4use integer;
5eval 'use warnings' if $] >= 5.006;
6
7use constant SUBFIELD_INDICATOR => "\x1F";
8use constant END_OF_FIELD => "\x1E";
9
10use vars qw( $ERROR );
11
12=head1 NAME
13
14MARC::Field - Perl extension for handling MARC fields
15
16=head1 VERSION
17
18Version 1.10
19
20 $Id: Field.pm 3430 2002-09-24 05:17:39Z jrm21 $
21
22=cut
23
24use vars '$VERSION'; $VERSION = '1.10';
25
26=head1 SYNOPSIS
27
28 use MARC::Field;
29
30 my $field =
31 MARC::Field->new(
32 245, '1', '0',
33 'a' => 'Raccoons and ripe corn / ',
34 'c' => 'Jim Arnosky.'
35 );
36 $field->add_subfields( "a", "1st ed." );
37
38=head1 DESCRIPTION
39
40Defines MARC fields for use in the MARC::Record module. I suppose
41you could use them on their own, but that wouldn't be very interesting.
42
43=head1 EXPORT
44
45None by default. Any errors are stored in C<$MARC::Field::ERROR>, which
46C<$MARC::Record> usually bubbles up to C<$MARC::Record::ERROR>.
47
48=head1 METHODS
49
50=head2 C<new(tag,indicator1,indicator2,code,data[,code,data...])>
51
52 my $record =
53 MARC::Field->new(
54 245, '1', '0',
55 'a' => 'Raccoons and ripe corn / ',
56 'c' => 'Jim Arnosky.'
57 );
58
59=cut
60
61sub new($) {
62 my $class = shift;
63 $class = ref($class) || $class;
64
65 my $tagno = shift;
66 ($tagno =~ /^\d\d\d$/)
67 or return _gripe( "Tag \"$tagno\" is not a valid tag number." );
68
69 my $self = bless {
70 _tag => $tagno,
71 _warnings => [],
72 }, $class;
73
74 if ( $tagno < 10 ) {
75 $self->{_data} = shift;
76 } else {
77 for my $indcode ( qw( _ind1 _ind2 ) ) {
78 my $indicator = shift;
79 if ( $indicator !~ /^[0-9 ]$/ ) {
80 $self->_warn( "Invalid indicator \"$indicator\" forced to blank" ) unless ($indicator eq "");
81 $indicator = " ";
82 }
83 $self->{$indcode} = $indicator;
84 } # for
85
86 (@_ >= 2)
87 or return _gripe( "Field $tagno must have at least one subfield" );
88
89 # Normally, we go thru add_subfields(), but internally we can cheat
90 $self->{_subfields} = [@_];
91 }
92
93 return $self;
94} # new()
95
96=head2 C<clone()>
97
98Makes a copy of the field. Note that this is not just the same as saying
99
100 my $newfield = $field;
101
102since that just makes a copy of the reference. To get a new object, you must
103
104 my $newfield = $field->clone;
105
106=cut
107
108sub clone {
109 my $self = shift;
110
111 my $tagno = $self->tag;
112
113 my $clone =
114 bless {
115 _tag => $tagno,
116 _warnings => [],
117 }, ref($self);
118
119 if ( $tagno < 10 ) {
120 $clone->{_data} = $self->{_data};
121 } else {
122 $clone->{_ind1} = $self->{_ind1};
123 $clone->{_ind2} = $self->{_ind2};
124 $clone->{_subfields} = [@{$self->{_subfields}}];
125 }
126
127 return $clone;
128}
129
130=head2 C<update()>
131
132Allows you to change the values of the field. You can update indicators
133and subfields like this:
134
135 $field->update( ind2 => '4', a => 'The ballad of Abe Lincoln');
136
137The amount of items modified will be returned to you as a result of the
138method call.
139
140If you want to update a field that has no indicators or subfields (000-009)
141just call update() with one argument, the string that you would like to
142set the field to.
143
144 $field = $record->field( '003' );
145 $field->update('IMchF');
146
147Note: when doing subfield updates be aware that C<update()> will only
148update the first occurrence. If you need to do anything more complicated
149you need to create a new field and use C<replace_with()>.
150
151=cut
152
153sub update {
154
155 my $self = shift;
156
157 ## tags 000 - 009 don't have indicators or subfields
158 if ( $self->tag() < 10 ) {
159 $self->{_data} = shift;
160 return(1);
161 }
162
163 ## otherwise we need to update subfields and indicators
164 my @data = @{$self->{_subfields}};
165 my $changes = 0;
166
167 while ( @_ ) {
168
169 my $arg = shift;
170 my $val = shift;
171
172 ## indicator update
173 if ($arg =~ /^ind[12]$/) {
174 $self->{"_$arg"} = $val;
175 $changes++;
176 }
177 ## subfield update
178 else {
179 for (my $i=0; $i<@data; $i=$i+2) {
180 if ($data[$i] eq $arg) {
181 $data[$i+1] = $val;
182 $changes++;
183 last;
184 }
185 }
186 }
187
188 }
189
190 ## synchronize our subfields
191 $self->{_subfields} = \@data;
192 return($changes);
193
194}
195
196=head2 C<replace_with()>
197
198Allows you to replace an existing field with a new one. You need to pass
199C<replace()> a MARC::Field object to replace the existing field with. For
200example:
201
202 $field = $record->field('245');
203 my $new_field = new MARC::Field('245','0','4','The ballad of Abe Lincoln.');
204 $field->replace_with($new_field);
205
206=cut
207
208sub replace_with {
209
210 my ($self,$new) = @_;
211 ref($new) =~ /^MARC::Field$/
212 or return _gripe("Must pass a MARC::Field object");
213
214 %$self = %$new;
215
216}
217
218
219=head2 C<tag()>
220
221Returns the three digit tag for the field.
222
223=cut
224
225sub tag {
226 my $self = shift;
227 return $self->{_tag};
228}
229
230=head2 C<indicator(indno)>
231
232Returns the specified indicator. Returns C<undef> and sets
233C<$MARC::Field::ERROR> if the I<indno> is not 1 or 2, or if
234the tag doesn't have indicators.
235
236=cut
237
238sub indicator($) {
239 my $self = shift;
240 my $indno = shift;
241
242 ($self->tag >= 10)
243 or return _gripe( "Fields below 010 do not have indicators" );
244
245 if ( $indno == 1 ) {
246 return $self->{_ind1};
247 } elsif ( $indno == 2 ) {
248 return $self->{_ind2};
249 } else {
250 return _gripe( "Indicator number must be 1 or 2" );
251 }
252}
253
254
255
256=head2 C<subfield(code)>
257
258Returns the text from the first subfield matching the subfield code.
259If no matching subfields are found, C<undef> is returned.
260
261If the tag is less than an 010, C<undef> is returned and
262C<$MARC::Field::ERROR> is set.
263
264=cut
265
266sub subfield {
267 my $self = shift;
268 my $code_wanted = shift;
269
270 ($self->tag >= 10)
271 or return _gripe( "Fields below 010 do not have subfields" );
272
273 my @data = @{$self->{_subfields}};
274 while ( defined( my $code = shift @data ) ) {
275 return shift @data if ( $code eq $code_wanted );
276 shift @data;
277 }
278
279 return undef;
280}
281
282=head2 C<subfields()>
283
284Returns all the subfields in the field. What's returned is a list of
285lists, where the inner list is a subfield code and the subfield data.
286
287For example, this might be the subfields from a 245 field:
288
289 [
290 [ 'a', 'Perl in a nutshell :' ],
291 [ 'b', 'A desktop quick reference.' ],
292 ]
293
294=cut
295
296sub subfields {
297 my $self = shift;
298
299 ($self->tag >= 10)
300 or return _gripe( "Fields below 010 do not have subfields" );
301
302 my @list;
303 my @data = @{$self->{_subfields}};
304 while ( defined( my $code = shift @data ) ) {
305 push( @list, [$code, shift @data] );
306 }
307 return @list;
308}
309
310sub _gripe(@) {
311 $ERROR = join( "", @_ );
312
313 warn $ERROR;
314
315 return undef;
316}
317
318=head2 C<data()>
319
320Returns the data part of the field, if the tag number is less than 10.
321
322=cut
323
324sub data($) {
325 my $self = shift;
326
327 ($self->{_tag} < 10)
328 or return _gripe( "data() is only for tags less than 10" );
329
330 my $data = shift;
331 $self->{_data} = $data if defined( $data );
332
333 return $self->{_data};
334}
335
336=head2 C<add_subfields(code,text[,code,text ...])>
337
338Adds subfields to the end of the subfield list.
339
340Returns the number of subfields added, or C<undef> if there was an error.
341
342=cut
343
344sub add_subfields(@) {
345 my $self = shift;
346
347 ($self->{_tag} >= 10)
348 or return _gripe( "Subfields are only for tags >= 10" );
349
350 push( @{$self->{_subfields}}, @_ );
351 return @_/2;
352}
353
354=head2 C<as_string()>
355
356Returns a string of all subfields run together, without the tag number.
357
358=cut
359
360sub as_string() {
361 my $self = shift;
362
363 return $self->{_data} if $self->tag < 10;
364
365 my @subs;
366
367 my @subdata = @{$self->{_subfields}};
368 while ( @subdata ) {
369 my $code = shift @subdata;
370 my $text = shift @subdata;
371 push( @subs, $text );
372 } # for
373
374 return join( " ", @subs );
375}
376
377
378=head2 C<as_formatted()>
379
380Returns a pretty string for printing in a MARC dump.
381
382=cut
383
384sub as_formatted() {
385 my $self = shift;
386
387 my @lines;
388
389 if ( $self->tag < 10 ) {
390 push( @lines, sprintf( "%03d %s", $self->{_tag}, $self->{_data} ) );
391 } else {
392 my $hanger = sprintf( "%03d %1.1s%1.1s", $self->{_tag}, $self->{_ind1}, $self->{_ind2} );
393
394 my @subdata = @{$self->{_subfields}};
395 while ( @subdata ) {
396 my $code = shift @subdata;
397 my $text = shift @subdata;
398 push( @lines, sprintf( "%-6.6s _%1.1s%s", $hanger, $code, $text ) );
399 $hanger = "";
400 } # for
401 }
402
403
404
405 return join( "\n", @lines );
406}
407
408
409=head2 C<as_usmarc()>
410
411Returns a string for putting into a USMARC file. It's really only
412useful by C<MARC::Record::as_usmarc()>.
413
414=cut
415
416sub as_usmarc() {
417 my $self = shift;
418
419 # Tags < 010 are pretty easy
420 if ( $self->tag < 10 ) {
421 return $self->data . END_OF_FIELD;
422 } else {
423 my @subs;
424 my @subdata = @{$self->{_subfields}};
425 while ( @subdata ) {
426 push( @subs, join( "", SUBFIELD_INDICATOR, shift @subdata, shift @subdata ) );
427 } # while
428
429 return join( "",
430 $self->indicator(1),
431 $self->indicator(2),
432 @subs,
433 END_OF_FIELD,
434 );
435 }
436}
437
438=head2 C<warnings()>
439
440Returns the warnings that were created when the record was read.
441These are things like "Invalid indicators converted to blanks".
442
443The warnings are items that you might be interested in, or might
444not. It depends on how stringently you're checking data. If
445you're doing some grunt data analysis, you probably don't care.
446
447=cut
448
449sub warnings() {
450 my $self = shift;
451
452 return @{$self->{_warnings}};
453}
454
455# NOTE: _warn is an object method
456sub _warn($) {
457 my $self = shift;
458
459 push( @{$self->{_warnings}}, join( "", @_ ) );
460}
461
4621;
463
464__END__
465
466=head1 SEE ALSO
467
468See the "SEE ALSO" section for L<MARC::Record>.
469
470=head1 TODO
471
472See the "TODO" section for L<MARC::Record>.
473
474=cut
475
476=head1 LICENSE
477
478This code may be distributed under the same terms as Perl itself.
479
480Please note that these modules are not products of or supported by the
481employers of the various contributors to the code.
482
483=head1 AUTHOR
484
485Andy Lester, E<lt>[email protected]<gt> or E<lt>[email protected]<gt>
486
487=cut
Note: See TracBrowser for help on using the repository browser.