| Filename | /usr/share/perl5/MARC/Field.pm |
| Statements | Executed 18 statements in 3.02ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 1.06ms | 1.22ms | MARC::Field::BEGIN@456 |
| 1 | 1 | 1 | 10µs | 20µs | MARC::Field::BEGIN@3 |
| 1 | 1 | 1 | 8µs | 42µs | MARC::Field::BEGIN@8 |
| 1 | 1 | 1 | 7µs | 40µs | MARC::Field::BEGIN@6 |
| 1 | 1 | 1 | 6µs | 23µs | MARC::Field::BEGIN@11 |
| 1 | 1 | 1 | 6µs | 10µs | MARC::Field::BEGIN@4 |
| 1 | 1 | 1 | 6µs | 7µs | MARC::Field::BEGIN@5 |
| 1 | 1 | 1 | 5µs | 26µs | MARC::Field::BEGIN@9 |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::_gripe |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::_normalize_arrayref |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::_warn |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::add_subfields |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::allow_controlfield_tags |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::as_formatted |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::as_string |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::as_usmarc |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::clone |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::data |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::delete_subfield |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::delete_subfields |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::disallow_controlfield_tags |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::indicator |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::is_control_field |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::is_controlfield_tag |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::is_valid_indicator |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::is_valid_tag |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::new |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::replace_with |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::set_indicator |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::set_tag |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::subfield |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::subfields |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::tag |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::update |
| 0 | 0 | 0 | 0s | 0s | MARC::Field::warnings |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package MARC::Field; | ||||
| 2 | |||||
| 3 | 2 | 21µs | 2 | 30µs | # spent 20µs (10+10) within MARC::Field::BEGIN@3 which was called:
# once (10µs+10µs) by MARC::Record::BEGIN@15 at line 3 # spent 20µs making 1 call to MARC::Field::BEGIN@3
# spent 10µs making 1 call to strict::import |
| 4 | 2 | 18µs | 2 | 14µs | # spent 10µs (6+4) within MARC::Field::BEGIN@4 which was called:
# once (6µs+4µs) by MARC::Record::BEGIN@15 at line 4 # spent 10µs making 1 call to MARC::Field::BEGIN@4
# spent 4µs making 1 call to warnings::import |
| 5 | 2 | 22µs | 2 | 9µs | # spent 7µs (6+1) within MARC::Field::BEGIN@5 which was called:
# once (6µs+1µs) by MARC::Record::BEGIN@15 at line 5 # spent 7µs making 1 call to MARC::Field::BEGIN@5
# spent 1µs making 1 call to integer::import |
| 6 | 2 | 31µs | 2 | 74µs | # spent 40µs (7+33) within MARC::Field::BEGIN@6 which was called:
# once (7µs+33µs) by MARC::Record::BEGIN@15 at line 6 # spent 40µs making 1 call to MARC::Field::BEGIN@6
# spent 33µs making 1 call to Exporter::import |
| 7 | |||||
| 8 | 2 | 27µs | 2 | 76µs | # spent 42µs (8+34) within MARC::Field::BEGIN@8 which was called:
# once (8µs+34µs) by MARC::Record::BEGIN@15 at line 8 # spent 42µs making 1 call to MARC::Field::BEGIN@8
# spent 34µs making 1 call to constant::import |
| 9 | 2 | 22µs | 2 | 46µs | # spent 26µs (5+20) within MARC::Field::BEGIN@9 which was called:
# once (5µs+20µs) by MARC::Record::BEGIN@15 at line 9 # spent 26µs making 1 call to MARC::Field::BEGIN@9
# spent 20µs making 1 call to constant::import |
| 10 | |||||
| 11 | 2 | 995µs | 2 | 40µs | # spent 23µs (6+17) within MARC::Field::BEGIN@11 which was called:
# once (6µs+17µs) by MARC::Record::BEGIN@15 at line 11 # spent 23µs making 1 call to MARC::Field::BEGIN@11
# spent 17µs making 1 call to vars::import |
| 12 | |||||
| 13 | =head1 NAME | ||||
| 14 | |||||
| 15 | MARC::Field - Perl extension for handling MARC fields | ||||
| 16 | |||||
| 17 | =head1 SYNOPSIS | ||||
| 18 | |||||
| 19 | use MARC::Field; | ||||
| 20 | |||||
| 21 | # If your system uses wacky control field tags, add them | ||||
| 22 | MARC::Field->allow_controlfield_tags('FMT', 'LLE'); | ||||
| 23 | |||||
| 24 | my $field = MARC::Field->new( 245, '1', '0', | ||||
| 25 | 'a' => 'Raccoons and ripe corn / ', | ||||
| 26 | 'c' => 'Jim Arnosky.' | ||||
| 27 | ); | ||||
| 28 | $field->add_subfields( "a", "1st ed." ); | ||||
| 29 | |||||
| 30 | =head1 DESCRIPTION | ||||
| 31 | |||||
| 32 | Defines MARC fields for use in the MARC::Record module. I suppose | ||||
| 33 | you could use them on their own, but that wouldn't be very interesting. | ||||
| 34 | |||||
| 35 | =head1 EXPORT | ||||
| 36 | |||||
| 37 | None by default. Any errors are stored in C<$MARC::Field::ERROR>, which | ||||
| 38 | C<$MARC::Record> usually bubbles up to C<$MARC::Record::ERROR>. | ||||
| 39 | |||||
| 40 | =head1 CLASS VARIABLES | ||||
| 41 | |||||
| 42 | B<extra_controlfield_tags>: Some systems (notably Ex Libris's Aleph) throw | ||||
| 43 | extra control fields in their MARC (e.g., Aleph's MARC-XML tends to have a | ||||
| 44 | C<FMT> control field). We keep a class-level hash to track to track them; it can | ||||
| 45 | be manipulated with C<allow_controlfield_tags> and c<disallow_controlfield_tags>. | ||||
| 46 | |||||
| 47 | =cut | ||||
| 48 | |||||
| 49 | 1 | 700ns | my %extra_controlfield_tags = (); | ||
| 50 | |||||
| 51 | |||||
| 52 | =head1 METHODS | ||||
| 53 | |||||
| 54 | =head2 new() | ||||
| 55 | |||||
| 56 | The constructor, which will return a MARC::Field object. Typically you will | ||||
| 57 | pass in the tag number, indicator 1, indicator 2, and then a list of any | ||||
| 58 | subfield/data pairs. For example: | ||||
| 59 | |||||
| 60 | my $field = MARC::Field->new( | ||||
| 61 | 245, '1', '0', | ||||
| 62 | 'a' => 'Raccoons and ripe corn / ', | ||||
| 63 | 'c' => 'Jim Arnosky.' | ||||
| 64 | ); | ||||
| 65 | |||||
| 66 | Or if you want to add a control field (< 010) that does not have indicators. | ||||
| 67 | |||||
| 68 | my $field = MARC::Field->new( '001', ' 14919759' ); | ||||
| 69 | |||||
| 70 | =cut | ||||
| 71 | |||||
| 72 | sub new { | ||||
| 73 | my $class = shift; | ||||
| 74 | $class = $class; | ||||
| 75 | |||||
| 76 | ## MARC spec indicates that tags can have alphabetical | ||||
| 77 | ## characters in them! If they do appear we assume that | ||||
| 78 | ## they have indicators like tags > 010 unless they've | ||||
| 79 | ## been previously defined as control tags using | ||||
| 80 | ## add_controlfield | ||||
| 81 | |||||
| 82 | my $tagno = shift; | ||||
| 83 | $class->is_valid_tag($tagno) | ||||
| 84 | or croak( "Tag \"$tagno\" is not a valid tag." ); | ||||
| 85 | my $is_control = $class->is_controlfield_tag($tagno); | ||||
| 86 | |||||
| 87 | my $self = bless { | ||||
| 88 | _tag => $tagno, | ||||
| 89 | _warnings => [], | ||||
| 90 | _is_control_field => $is_control, | ||||
| 91 | }, $class; | ||||
| 92 | |||||
| 93 | if ( $is_control ) { | ||||
| 94 | $self->{_data} = shift; | ||||
| 95 | $self->_warn("Too much data for control field '$tagno'") if (@_); | ||||
| 96 | } else { | ||||
| 97 | for my $indcode ( qw( _ind1 _ind2 ) ) { | ||||
| 98 | my $indicator = shift; | ||||
| 99 | defined($indicator) or croak("Field $tagno must have indicators (use ' ' for empty indicators)"); | ||||
| 100 | unless ($self->is_valid_indicator($indicator)) { | ||||
| 101 | $self->_warn( "Invalid indicator \"$indicator\" forced to blank" ) unless ($indicator eq ""); | ||||
| 102 | $indicator = " "; | ||||
| 103 | } | ||||
| 104 | $self->{$indcode} = $indicator; | ||||
| 105 | } # for | ||||
| 106 | |||||
| 107 | (@_ >= 2) | ||||
| 108 | or croak( "Field $tagno must have at least one subfield" ); | ||||
| 109 | |||||
| 110 | # Normally, we go thru add_subfields(), but internally we can cheat | ||||
| 111 | $self->{_subfields} = [@_]; | ||||
| 112 | } | ||||
| 113 | |||||
| 114 | return $self; | ||||
| 115 | } # new() | ||||
| 116 | |||||
| 117 | |||||
| 118 | =head2 tag() | ||||
| 119 | |||||
| 120 | Returns the three digit tag for the field. | ||||
| 121 | |||||
| 122 | =cut | ||||
| 123 | |||||
| 124 | sub tag { | ||||
| 125 | my $self = shift; | ||||
| 126 | return $self->{_tag}; | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | =head2 set_tag(tag) | ||||
| 130 | |||||
| 131 | Changes the tag number of this field. Updates the control status accordingly. | ||||
| 132 | Will C<croak> if an invalid value is passed in. | ||||
| 133 | |||||
| 134 | =cut | ||||
| 135 | |||||
| 136 | sub set_tag { | ||||
| 137 | my ( $self, $tagno ) = @_; | ||||
| 138 | |||||
| 139 | $self->is_valid_tag($tagno) | ||||
| 140 | or croak("Tag \"$tagno\" is not a valid tag."); | ||||
| 141 | $self->{_tag} = $tagno; | ||||
| 142 | $self->{_is_control_field} = $self->is_controlfield_tag($tagno); | ||||
| 143 | } | ||||
| 144 | |||||
| 145 | =head2 indicator(indno) | ||||
| 146 | |||||
| 147 | Returns the specified indicator. Returns C<undef> and logs | ||||
| 148 | a warning if field is a control field and thus doesn't have | ||||
| 149 | indicators. If the field is not a control field, croaks | ||||
| 150 | if the I<indno> is not 1 or 2. | ||||
| 151 | |||||
| 152 | =cut | ||||
| 153 | |||||
| 154 | sub indicator { | ||||
| 155 | my $self = shift; | ||||
| 156 | my $indno = shift; | ||||
| 157 | |||||
| 158 | if ($self->is_control_field) { | ||||
| 159 | $self->_warn( "Control fields (generally, those with tags below 010) do not have indicators" ); | ||||
| 160 | return; | ||||
| 161 | } | ||||
| 162 | |||||
| 163 | if ( $indno == 1 ) { | ||||
| 164 | return $self->{_ind1}; | ||||
| 165 | } elsif ( $indno == 2 ) { | ||||
| 166 | return $self->{_ind2}; | ||||
| 167 | } else { | ||||
| 168 | croak( "Indicator number must be 1 or 2" ); | ||||
| 169 | } | ||||
| 170 | } | ||||
| 171 | |||||
| 172 | =head2 set_indicator($indno, $indval) | ||||
| 173 | |||||
| 174 | Set the indicator position I<$indno> to the value | ||||
| 175 | specified by I<$indval>. Croaks if the indicator position, | ||||
| 176 | is invalid, the field is a control field and thus | ||||
| 177 | doesn't have indicators, or if the new indicator value | ||||
| 178 | is invalid. | ||||
| 179 | |||||
| 180 | =cut | ||||
| 181 | |||||
| 182 | sub set_indicator { | ||||
| 183 | my $self = shift; | ||||
| 184 | my $indno = shift; | ||||
| 185 | my $indval = shift; | ||||
| 186 | |||||
| 187 | croak('Indicator number must be 1 or 2') | ||||
| 188 | unless defined $indno && $indno =~ /^[12]$/; | ||||
| 189 | croak('Cannot set indicator for control field') | ||||
| 190 | if $self->is_control_field; | ||||
| 191 | croak('Indicator value is invalid') unless $self->is_valid_indicator($indval); | ||||
| 192 | |||||
| 193 | $self->{"_ind$indno"} = $indval; | ||||
| 194 | } | ||||
| 195 | |||||
| 196 | =head2 allow_controlfield_tags($tag, $tag2, ...) | ||||
| 197 | |||||
| 198 | Add $tags to class-level list of strings to consider valid control fields tags (in addition to 001 through 009). | ||||
| 199 | Tags must have three characters. | ||||
| 200 | |||||
| 201 | =cut | ||||
| 202 | |||||
| 203 | sub allow_controlfield_tags { | ||||
| 204 | my $self = shift; | ||||
| 205 | foreach my $tag (@_) { | ||||
| 206 | $extra_controlfield_tags{$tag} = 1; | ||||
| 207 | } | ||||
| 208 | } | ||||
| 209 | |||||
| 210 | =head2 disallow_controlfield_tags($tag, $tag2, ...) | ||||
| 211 | =head2 disallow_controlfield_tags('*') | ||||
| 212 | |||||
| 213 | Revoke the validity of a control field tag previously added with allow_controlfield_tags. As a special case, | ||||
| 214 | if you pass the string '*' it will clear out all previously-added tags. | ||||
| 215 | |||||
| 216 | NOTE that this will only deal with stuff added with allow_controlfield_tags; you can't disallow '001'. | ||||
| 217 | |||||
| 218 | =cut | ||||
| 219 | |||||
| 220 | sub disallow_controlfield_tags { | ||||
| 221 | my $self = shift; | ||||
| 222 | if ($_[0] eq '*') { | ||||
| 223 | %extra_controlfield_tags = (); | ||||
| 224 | return; | ||||
| 225 | } | ||||
| 226 | foreach my $tag (@_) { | ||||
| 227 | delete $extra_controlfield_tags{$tag}; | ||||
| 228 | } | ||||
| 229 | } | ||||
| 230 | |||||
| 231 | =head2 is_valid_tag($tag) -- is the given tag valid? | ||||
| 232 | |||||
| 233 | Generally called as a class method (e.g., MARC::Field->is_valid_tag('001')) | ||||
| 234 | |||||
| 235 | =cut | ||||
| 236 | |||||
| 237 | sub is_valid_tag { | ||||
| 238 | my $self = shift; | ||||
| 239 | my $tag = shift; | ||||
| 240 | return 1 if defined $tag && $tag =~ /^[0-9A-Za-z]{3}$/; | ||||
| 241 | return 0; | ||||
| 242 | } | ||||
| 243 | |||||
| 244 | =head2 is_valid_indicator($indval) -- is the given indicator value valid? | ||||
| 245 | |||||
| 246 | Generally called as a class method (e.g., MARC::Field->is_valid_indicator('4')) | ||||
| 247 | |||||
| 248 | =cut | ||||
| 249 | |||||
| 250 | sub is_valid_indicator { | ||||
| 251 | my $self = shift; | ||||
| 252 | my $indval = shift; | ||||
| 253 | return 1 if defined $indval && $indval =~ /^[0-9A-Za-z ]$/; | ||||
| 254 | return 0; | ||||
| 255 | } | ||||
| 256 | |||||
| 257 | =head2 is_controlfield_tag($tag) -- does the given tag denote a control field? | ||||
| 258 | |||||
| 259 | Generally called as a class method (e.g., MARC::Field->is_controlfield_tag('001')) | ||||
| 260 | |||||
| 261 | =cut | ||||
| 262 | |||||
| 263 | sub is_controlfield_tag | ||||
| 264 | { | ||||
| 265 | my $self = shift; | ||||
| 266 | my $tag = shift; | ||||
| 267 | return 1 if ($extra_controlfield_tags{$tag}); | ||||
| 268 | return 1 if (($tag =~ /^\d+$/) && ($tag < 10)); | ||||
| 269 | return 0; # otherwise, it's not a control field | ||||
| 270 | } | ||||
| 271 | |||||
| 272 | |||||
| 273 | =head2 is_control_field() | ||||
| 274 | |||||
| 275 | Tells whether this field is one of the control tags from 001-009. | ||||
| 276 | |||||
| 277 | =cut | ||||
| 278 | |||||
| 279 | sub is_control_field { | ||||
| 280 | my $self = shift; | ||||
| 281 | return $self->{_is_control_field}; | ||||
| 282 | } | ||||
| 283 | |||||
| 284 | =head2 subfield(code) | ||||
| 285 | |||||
| 286 | When called in a scalar context returns the text from the first subfield | ||||
| 287 | matching the subfield code. | ||||
| 288 | |||||
| 289 | my $subfield = $field->subfield( 'a' ); | ||||
| 290 | |||||
| 291 | Or if you think there might be more than one you can get all of them by | ||||
| 292 | calling in a list context: | ||||
| 293 | |||||
| 294 | my @subfields = $field->subfield( 'a' ); | ||||
| 295 | |||||
| 296 | If no matching subfields are found, C<undef> is returned in a scalar context | ||||
| 297 | and an empty list in a list context. | ||||
| 298 | |||||
| 299 | If the tag is a control field, C<undef> is returned and | ||||
| 300 | C<$MARC::Field::ERROR> is set. | ||||
| 301 | |||||
| 302 | =cut | ||||
| 303 | |||||
| 304 | sub subfield { | ||||
| 305 | my $self = shift; | ||||
| 306 | my $code_wanted = shift; | ||||
| 307 | |||||
| 308 | croak( "Control fields (generally, just tags below 010) do not have subfields, use data()" ) | ||||
| 309 | if $self->is_control_field; | ||||
| 310 | |||||
| 311 | my @data = @{$self->{_subfields}}; | ||||
| 312 | my @found; | ||||
| 313 | while ( defined( my $code = shift @data ) ) { | ||||
| 314 | if ( $code eq $code_wanted ) { | ||||
| 315 | push( @found, shift @data ); | ||||
| 316 | } else { | ||||
| 317 | shift @data; | ||||
| 318 | } | ||||
| 319 | } | ||||
| 320 | if ( wantarray() ) { return @found; } | ||||
| 321 | return( $found[0] ); | ||||
| 322 | } | ||||
| 323 | |||||
| 324 | =head2 subfields() | ||||
| 325 | |||||
| 326 | Returns all the subfields in the field. What's returned is a list of | ||||
| 327 | list refs, where the inner list is a subfield code and the subfield data. | ||||
| 328 | |||||
| 329 | For example, this might be the subfields from a 245 field: | ||||
| 330 | |||||
| 331 | ( | ||||
| 332 | [ 'a', 'Perl in a nutshell :' ], | ||||
| 333 | [ 'b', 'A desktop quick reference.' ], | ||||
| 334 | ) | ||||
| 335 | |||||
| 336 | =cut | ||||
| 337 | |||||
| 338 | sub subfields { | ||||
| 339 | my $self = shift; | ||||
| 340 | |||||
| 341 | if ($self->is_control_field) { | ||||
| 342 | $self->_warn( "Control fields (generally, just tags below 010) do not have subfields" ); | ||||
| 343 | return; | ||||
| 344 | } | ||||
| 345 | |||||
| 346 | my @list; | ||||
| 347 | my @data = @{$self->{_subfields}}; | ||||
| 348 | while ( defined( my $code = shift @data ) ) { | ||||
| 349 | push( @list, [$code, shift @data] ); | ||||
| 350 | } | ||||
| 351 | return @list; | ||||
| 352 | } | ||||
| 353 | |||||
| 354 | =head2 data() | ||||
| 355 | |||||
| 356 | Returns the data part of the field, if the tag number is less than 10. | ||||
| 357 | |||||
| 358 | =cut | ||||
| 359 | |||||
| 360 | sub data { | ||||
| 361 | my $self = shift; | ||||
| 362 | |||||
| 363 | croak( "data() is only for control fields (generally, just tags below 010) , use subfield()" ) | ||||
| 364 | unless $self->is_control_field; | ||||
| 365 | |||||
| 366 | $self->{_data} = $_[0] if @_; | ||||
| 367 | |||||
| 368 | return $self->{_data}; | ||||
| 369 | } | ||||
| 370 | |||||
| 371 | =head2 add_subfields(code,text[,code,text ...]) | ||||
| 372 | |||||
| 373 | Adds subfields to the end of the subfield list. | ||||
| 374 | |||||
| 375 | $field->add_subfields( 'c' => '1985' ); | ||||
| 376 | |||||
| 377 | Returns the number of subfields added, or C<undef> if there was an error. | ||||
| 378 | |||||
| 379 | =cut | ||||
| 380 | |||||
| 381 | sub add_subfields { | ||||
| 382 | my $self = shift; | ||||
| 383 | |||||
| 384 | croak( "Subfields are only for data fields (generally, just tags >= 010)" ) | ||||
| 385 | if $self->is_control_field; | ||||
| 386 | |||||
| 387 | push( @{$self->{_subfields}}, @_ ); | ||||
| 388 | return @_/2; | ||||
| 389 | } | ||||
| 390 | |||||
| 391 | =head2 delete_subfield() | ||||
| 392 | |||||
| 393 | delete_subfield() allows you to remove subfields from a field: | ||||
| 394 | |||||
| 395 | # delete any subfield a in the field | ||||
| 396 | $field->delete_subfield(code => 'a'); | ||||
| 397 | |||||
| 398 | # delete any subfield a or u in the field | ||||
| 399 | $field->delete_subfield(code => ['a', 'u']); | ||||
| 400 | |||||
| 401 | # delete any subfield code matching a compiled regular expression | ||||
| 402 | $field->delete_subfield(code => qr/[^a-z0-9]/); | ||||
| 403 | |||||
| 404 | If you want to only delete subfields at a particular position you can | ||||
| 405 | use the pos parameter: | ||||
| 406 | |||||
| 407 | # delete subfield u at the first position | ||||
| 408 | $field->delete_subfield(code => 'u', pos => 0); | ||||
| 409 | |||||
| 410 | # delete subfield u at first or second position | ||||
| 411 | $field->delete_subfield(code => 'u', pos => [0,1]); | ||||
| 412 | |||||
| 413 | # delete the second subfield, no matter what it is | ||||
| 414 | $field->delete_subfield(pos => 1); | ||||
| 415 | |||||
| 416 | You can specify a regex to for only deleting subfields that match: | ||||
| 417 | |||||
| 418 | # delete any subfield u that matches zombo.com | ||||
| 419 | $field->delete_subfield(code => 'u', match => qr/zombo.com/); | ||||
| 420 | |||||
| 421 | # delete any subfield that matches quux | ||||
| 422 | $field->delete_subfield(match => qr/quux/); | ||||
| 423 | |||||
| 424 | You can also pass a single subfield label: | ||||
| 425 | |||||
| 426 | # delete all subfield u | ||||
| 427 | $field->delete_subfield('u'); | ||||
| 428 | |||||
| 429 | =cut | ||||
| 430 | |||||
| 431 | sub delete_subfield { | ||||
| 432 | my ($self, @options) = @_; | ||||
| 433 | |||||
| 434 | my %options; | ||||
| 435 | if (scalar(@options) == 1) { | ||||
| 436 | $options{code} = $options[0]; | ||||
| 437 | } elsif (0 == scalar(@options) % 2) { | ||||
| 438 | %options = @options; | ||||
| 439 | } else { | ||||
| 440 | croak 'delete_subfield must be called with single scalar or a hash'; | ||||
| 441 | } | ||||
| 442 | |||||
| 443 | my $codes = _normalize_arrayref($options{code}); | ||||
| 444 | my $positions = _normalize_arrayref($options{'pos'}); | ||||
| 445 | my $match = $options{match}; | ||||
| 446 | |||||
| 447 | croak 'match must be a compiled regex' | ||||
| 448 | if $match and ref($match) ne 'Regexp'; | ||||
| 449 | |||||
| 450 | croak 'must supply subfield code(s) and/or subfield position(s) and/or match patterns to delete_subfield' | ||||
| 451 | unless $match or (@$codes > 0) or (@$positions > 0); | ||||
| 452 | |||||
| 453 | my @current_subfields = @{$self->{_subfields}}; | ||||
| 454 | my @new_subfields = (); | ||||
| 455 | my $removed = 0; | ||||
| 456 | 2 | 1.88ms | 1 | 1.22ms | # spent 1.22ms (1.06+162µs) within MARC::Field::BEGIN@456 which was called:
# once (1.06ms+162µs) by MARC::Record::BEGIN@15 at line 456 # spent 1.22ms making 1 call to MARC::Field::BEGIN@456 |
| 457 | |||||
| 458 | while (@current_subfields > 0) { | ||||
| 459 | $subfield_num += 1; | ||||
| 460 | my $subfield_code = shift @current_subfields; | ||||
| 461 | my $subfield_value = shift @current_subfields; | ||||
| 462 | if ((@$codes==0 or | ||||
| 463 | grep { | ||||
| 464 | (ref($_) eq 'Regexp' && $subfield_code =~ $_) || | ||||
| 465 | (ref($_) ne 'Regexp' && $_ eq $subfield_code) | ||||
| 466 | } @$codes) | ||||
| 467 | and (!$match or $subfield_value =~ $match) | ||||
| 468 | and (@$positions==0 or grep {$_ == $subfield_num} @$positions)) { | ||||
| 469 | $removed += 1; | ||||
| 470 | next; | ||||
| 471 | } | ||||
| 472 | push( @new_subfields, $subfield_code, $subfield_value); | ||||
| 473 | } | ||||
| 474 | $self->{_subfields} = \@new_subfields; | ||||
| 475 | return $removed; | ||||
| 476 | } | ||||
| 477 | |||||
| 478 | =head2 delete_subfields() | ||||
| 479 | |||||
| 480 | Delete all subfields with a given subfield code. This is here for backwards | ||||
| 481 | compatibility, you should use the more flexible delete_subfield(). | ||||
| 482 | |||||
| 483 | =cut | ||||
| 484 | |||||
| 485 | sub delete_subfields { | ||||
| 486 | my ($self, $code) = @_; | ||||
| 487 | return $self->delete_subfield(code => $code); | ||||
| 488 | } | ||||
| 489 | |||||
| 490 | =head2 update() | ||||
| 491 | |||||
| 492 | Allows you to change the values of the field. You can update indicators | ||||
| 493 | and subfields like this: | ||||
| 494 | |||||
| 495 | $field->update( ind2 => '4', a => 'The ballad of Abe Lincoln'); | ||||
| 496 | |||||
| 497 | If you attempt to update a subfield which does not currently exist in the field, | ||||
| 498 | then a new subfield will be appended to the field. If you don't like this | ||||
| 499 | auto-vivification you must check for the existence of the subfield prior to | ||||
| 500 | update. | ||||
| 501 | |||||
| 502 | if ( $field->subfield( 'a' ) ) { | ||||
| 503 | $field->update( 'a' => 'Cryptonomicon' ); | ||||
| 504 | } | ||||
| 505 | |||||
| 506 | If you want to update a field that has no indicators or subfields (000-009) | ||||
| 507 | just call update() with one argument, the string that you would like to | ||||
| 508 | set the field to. | ||||
| 509 | |||||
| 510 | $field = $record->field( '003' ); | ||||
| 511 | $field->update('IMchF'); | ||||
| 512 | |||||
| 513 | Note: when doing subfield updates be aware that C<update()> will only | ||||
| 514 | update the first occurrence. If you need to do anything more complicated | ||||
| 515 | you will probably need to create a new field and use C<replace_with()>. | ||||
| 516 | |||||
| 517 | Returns the number of items modified. | ||||
| 518 | |||||
| 519 | =cut | ||||
| 520 | |||||
| 521 | sub update { | ||||
| 522 | my $self = shift; | ||||
| 523 | |||||
| 524 | ## tags 000 - 009 don't have indicators or subfields | ||||
| 525 | if ( $self->is_control_field ) { | ||||
| 526 | $self->{_data} = shift; | ||||
| 527 | return(1); | ||||
| 528 | } | ||||
| 529 | |||||
| 530 | ## otherwise we need to update subfields and indicators | ||||
| 531 | my @data = @{$self->{_subfields}}; | ||||
| 532 | my $changes = 0; | ||||
| 533 | |||||
| 534 | while ( @_ ) { | ||||
| 535 | |||||
| 536 | my $arg = shift; | ||||
| 537 | my $val = shift; | ||||
| 538 | |||||
| 539 | ## indicator update | ||||
| 540 | if ($arg =~ /^ind[12]$/) { | ||||
| 541 | $self->{"_$arg"} = $val; | ||||
| 542 | $changes++; | ||||
| 543 | } | ||||
| 544 | |||||
| 545 | ## subfield update | ||||
| 546 | else { | ||||
| 547 | my $found = 0; | ||||
| 548 | ## update existing subfield | ||||
| 549 | for ( my $i=0; $i<@data; $i+=2 ) { | ||||
| 550 | if ($data[$i] eq $arg) { | ||||
| 551 | $data[$i+1] = $val; | ||||
| 552 | $found = 1; | ||||
| 553 | $changes++; | ||||
| 554 | last; | ||||
| 555 | } | ||||
| 556 | } # for | ||||
| 557 | |||||
| 558 | ## append new subfield | ||||
| 559 | if ( !$found ) { | ||||
| 560 | push( @data, $arg, $val ); | ||||
| 561 | $changes++; | ||||
| 562 | } | ||||
| 563 | } | ||||
| 564 | |||||
| 565 | } # while | ||||
| 566 | |||||
| 567 | ## synchronize our subfields | ||||
| 568 | $self->{_subfields} = \@data; | ||||
| 569 | return($changes); | ||||
| 570 | |||||
| 571 | } | ||||
| 572 | |||||
| 573 | =head2 replace_with() | ||||
| 574 | |||||
| 575 | Allows you to replace an existing field with a new one. You need to pass | ||||
| 576 | C<replace()> a MARC::Field object to replace the existing field with. For | ||||
| 577 | example: | ||||
| 578 | |||||
| 579 | $field = $record->field('245'); | ||||
| 580 | my $new_field = new MARC::Field('245','0','4','The ballad of Abe Lincoln.'); | ||||
| 581 | $field->replace_with($new_field); | ||||
| 582 | |||||
| 583 | Doesn't return a meaningful or reliable value. | ||||
| 584 | |||||
| 585 | =cut | ||||
| 586 | |||||
| 587 | sub replace_with { | ||||
| 588 | |||||
| 589 | my ($self,$new) = @_; | ||||
| 590 | ref($new) =~ /^MARC::Field$/ | ||||
| 591 | or croak("Must pass a MARC::Field object"); | ||||
| 592 | |||||
| 593 | %$self = %$new; | ||||
| 594 | |||||
| 595 | } | ||||
| 596 | |||||
| 597 | |||||
| 598 | =head2 as_string( [$subfields] [, $delimiter] ) | ||||
| 599 | |||||
| 600 | Returns a string of all subfields run together. A space is added to | ||||
| 601 | the result between each subfield, unless the delimiter parameter is | ||||
| 602 | passed. The tag number and subfield character are not included. | ||||
| 603 | |||||
| 604 | Subfields appear in the output string in the order in which they | ||||
| 605 | occur in the field. | ||||
| 606 | |||||
| 607 | If C<$subfields> is specified, then only those subfields will be included. | ||||
| 608 | |||||
| 609 | my $field = MARC::Field->new( | ||||
| 610 | 245, '1', '0', | ||||
| 611 | 'a' => 'Abraham Lincoln', | ||||
| 612 | 'h' => '[videorecording] :', | ||||
| 613 | 'b' => 'preserving the union /', | ||||
| 614 | 'c' => 'A&E Home Video.' | ||||
| 615 | ); | ||||
| 616 | print $field->as_string( 'abh' ); # Only those three subfields | ||||
| 617 | # prints 'Abraham Lincoln [videorecording] : preserving the union /'. | ||||
| 618 | print $field->as_string( 'ab', '--' ); # Only those two subfields, with a delimiter | ||||
| 619 | # prints 'Abraham Lincoln--preserving the union /'. | ||||
| 620 | |||||
| 621 | Note that subfield h comes before subfield b in the output. | ||||
| 622 | |||||
| 623 | =cut | ||||
| 624 | |||||
| 625 | sub as_string { | ||||
| 626 | my $self = shift; | ||||
| 627 | my $subfields = shift; | ||||
| 628 | my $delimiter = shift; | ||||
| 629 | $delimiter = " " unless defined $delimiter; | ||||
| 630 | |||||
| 631 | if ( $self->is_control_field ) { | ||||
| 632 | return $self->{_data}; | ||||
| 633 | } | ||||
| 634 | |||||
| 635 | my @subs; | ||||
| 636 | |||||
| 637 | my $subs = $self->{_subfields}; | ||||
| 638 | my $nfields = @$subs / 2; | ||||
| 639 | for my $i ( 1..$nfields ) { | ||||
| 640 | my $offset = ($i-1)*2; | ||||
| 641 | my $code = $subs->[$offset]; | ||||
| 642 | my $text = $subs->[$offset+1]; | ||||
| 643 | push( @subs, $text ) if !defined($subfields) || $code =~ /^[$subfields]$/; | ||||
| 644 | } # for | ||||
| 645 | |||||
| 646 | return join( $delimiter, @subs ); | ||||
| 647 | } | ||||
| 648 | |||||
| 649 | |||||
| 650 | =head2 as_formatted() | ||||
| 651 | |||||
| 652 | Returns a pretty string for printing in a MARC dump. | ||||
| 653 | |||||
| 654 | =cut | ||||
| 655 | |||||
| 656 | sub as_formatted { | ||||
| 657 | my $self = shift; | ||||
| 658 | |||||
| 659 | my @lines; | ||||
| 660 | |||||
| 661 | if ( $self->is_control_field ) { | ||||
| 662 | push( @lines, sprintf( "%03s %s", $self->{_tag}, $self->{_data} ) ); | ||||
| 663 | } else { | ||||
| 664 | my $hanger = sprintf( "%03s %1.1s%1.1s", $self->{_tag}, $self->{_ind1}, $self->{_ind2} ); | ||||
| 665 | |||||
| 666 | my $subs = $self->{_subfields}; | ||||
| 667 | my $nfields = @$subs / 2; | ||||
| 668 | my $offset = 0; | ||||
| 669 | for my $i ( 1..$nfields ) { | ||||
| 670 | push( @lines, sprintf( "%-6.6s _%1.1s%s", $hanger, $subs->[$offset++], $subs->[$offset++] ) ); | ||||
| 671 | $hanger = ""; | ||||
| 672 | } # for | ||||
| 673 | } | ||||
| 674 | |||||
| 675 | return join( "\n", @lines ); | ||||
| 676 | } | ||||
| 677 | |||||
| 678 | |||||
| 679 | =head2 as_usmarc() | ||||
| 680 | |||||
| 681 | Returns a string for putting into a USMARC file. It's really only | ||||
| 682 | useful for C<MARC::Record::as_usmarc()>. | ||||
| 683 | |||||
| 684 | =cut | ||||
| 685 | |||||
| 686 | sub as_usmarc { | ||||
| 687 | my $self = shift; | ||||
| 688 | |||||
| 689 | # Control fields are pretty easy | ||||
| 690 | if ( $self->is_control_field ) { | ||||
| 691 | return $self->data . END_OF_FIELD; | ||||
| 692 | } else { | ||||
| 693 | my @subs; | ||||
| 694 | my @subdata = @{$self->{_subfields}}; | ||||
| 695 | while ( @subdata ) { | ||||
| 696 | push( @subs, join( "", SUBFIELD_INDICATOR, shift @subdata, shift @subdata ) ); | ||||
| 697 | } # while | ||||
| 698 | |||||
| 699 | return | ||||
| 700 | join( "", | ||||
| 701 | $self->indicator(1), | ||||
| 702 | $self->indicator(2), | ||||
| 703 | @subs, | ||||
| 704 | END_OF_FIELD, ); | ||||
| 705 | } | ||||
| 706 | } | ||||
| 707 | |||||
| 708 | =head2 clone() | ||||
| 709 | |||||
| 710 | Makes a copy of the field. Note that this is not just the same as saying | ||||
| 711 | |||||
| 712 | my $newfield = $field; | ||||
| 713 | |||||
| 714 | since that just makes a copy of the reference. To get a new object, you must | ||||
| 715 | |||||
| 716 | my $newfield = $field->clone; | ||||
| 717 | |||||
| 718 | Returns a MARC::Field record. | ||||
| 719 | |||||
| 720 | =cut | ||||
| 721 | |||||
| 722 | sub clone { | ||||
| 723 | my $self = shift; | ||||
| 724 | |||||
| 725 | my $tagno = $self->{_tag}; | ||||
| 726 | my $is_control = $self->is_controlfield_tag($tagno); | ||||
| 727 | |||||
| 728 | my $clone = | ||||
| 729 | bless { | ||||
| 730 | _tag => $tagno, | ||||
| 731 | _warnings => [], | ||||
| 732 | _is_control_field => $is_control, | ||||
| 733 | }, ref($self); | ||||
| 734 | |||||
| 735 | if ( $is_control ) { | ||||
| 736 | $clone->{_data} = $self->{_data}; | ||||
| 737 | } else { | ||||
| 738 | $clone->{_ind1} = $self->{_ind1}; | ||||
| 739 | $clone->{_ind2} = $self->{_ind2}; | ||||
| 740 | $clone->{_subfields} = [@{$self->{_subfields}}]; | ||||
| 741 | } | ||||
| 742 | |||||
| 743 | return $clone; | ||||
| 744 | } | ||||
| 745 | |||||
| 746 | =head2 warnings() | ||||
| 747 | |||||
| 748 | Returns the warnings that were created when the record was read. | ||||
| 749 | These are things like "Invalid indicators converted to blanks". | ||||
| 750 | |||||
| 751 | The warnings are items that you might be interested in, or might | ||||
| 752 | not. It depends on how stringently you're checking data. If | ||||
| 753 | you're doing some grunt data analysis, you probably don't care. | ||||
| 754 | |||||
| 755 | =cut | ||||
| 756 | |||||
| 757 | sub warnings { | ||||
| 758 | my $self = shift; | ||||
| 759 | |||||
| 760 | return @{$self->{_warnings}}; | ||||
| 761 | } | ||||
| 762 | |||||
| 763 | # NOTE: _warn is an object method | ||||
| 764 | sub _warn { | ||||
| 765 | my $self = shift; | ||||
| 766 | |||||
| 767 | push( @{$self->{_warnings}}, join( "", @_ ) ); | ||||
| 768 | } | ||||
| 769 | |||||
| 770 | sub _gripe { | ||||
| 771 | $ERROR = join( "", @_ ); | ||||
| 772 | |||||
| 773 | warn $ERROR; | ||||
| 774 | |||||
| 775 | return; | ||||
| 776 | } | ||||
| 777 | |||||
| 778 | sub _normalize_arrayref { | ||||
| 779 | my $ref = shift; | ||||
| 780 | if (ref($ref) eq 'ARRAY') { return $ref } | ||||
| 781 | elsif (defined $ref) { return [$ref] } | ||||
| 782 | return []; | ||||
| 783 | } | ||||
| 784 | |||||
| 785 | |||||
| 786 | 1 | 2µs | 1; | ||
| 787 | |||||
| 788 | __END__ |