MARC-Record

 view release on metacpan or  search on metacpan

lib/MARC/Field.pm  view on Meta::CPAN

        my $subfield_value = shift @current_subfields;
        if ((@$codes==0 or 
            grep {
                (ref($_) eq 'Regexp' && $subfield_code =~ $_) ||
                (ref($_) ne 'Regexp' && $_ eq $subfield_code)
            } @$codes)
            and (!$match or $subfield_value =~ $match) 
            and (@$positions==0 or grep {$_ == $subfield_num} @$positions)) {
            $removed += 1;
            next;
        }
        push( @new_subfields, $subfield_code, $subfield_value);
    }
    $self->{_subfields} = \@new_subfields;
    return $removed;
}

=head2 delete_subfields()

Delete all subfields with a given subfield code. This is here for backwards
compatibility, you should use the more flexible delete_subfield().

=cut

sub delete_subfields {
    my ($self, $code) = @_;
    return $self->delete_subfield(code => $code);
}

=head2 update()

Allows you to change the values of the field. You can update indicators
and subfields like this:

  $field->update( ind2 => '4', a => 'The ballad of Abe Lincoln');

If you attempt to update a subfield which does not currently exist in the field,
then a new subfield will be appended to the field. If you don't like this
auto-vivification you must check for the existence of the subfield prior to
update.

  if ( $field->subfield( 'a' ) ) {
    $field->update( 'a' => 'Cryptonomicon' );
  }

If you want to update a field that has no indicators or subfields (000-009)
just call update() with one argument, the string that you would like to
set the field to.

  $field = $record->field( '003' );
  $field->update('IMchF');

Note: when doing subfield updates be aware that C<update()> will only
update the first occurrence. If you need to do anything more complicated
you will probably need to create a new field and use C<replace_with()>.

Returns the number of items modified.

=cut

sub update {
    my $self = shift;

    ## tags 000 - 009 don't have indicators or subfields
    if ( $self->is_control_field ) {
        $self->{_data} = shift;
        return(1);
    }

    ## otherwise we need to update subfields and indicators
    my @data = @{$self->{_subfields}};
    my $changes = 0;

    while ( @_ ) {

        my $arg = shift;
        my $val = shift;

        ## indicator update
        if ($arg =~ /^ind[12]$/) {
            $self->{"_$arg"} = $val;
            $changes++;
        }

        ## subfield update
        else {
            my $found = 0;
            ## update existing subfield
            for ( my $i=0; $i<@data; $i+=2 ) {
                if ($data[$i] eq $arg) {
                    $data[$i+1] = $val;
                    $found = 1;
                    $changes++;
                    last;
                }
            } # for

            ## append new subfield
            if ( !$found ) {
                push( @data, $arg, $val );
                $changes++;
            }
        }

    } # while

    ## synchronize our subfields
    $self->{_subfields} = \@data;
    return($changes);

}

=head2 replace_with()

Allows you to replace an existing field with a new one. You need to pass
C<replace()> a MARC::Field object to replace the existing field with. For
example:

  $field = $record->field('245');
  my $new_field = new MARC::Field('245','0','4','The ballad of Abe Lincoln.');
  $field->replace_with($new_field);



( run in 0.720 second using v1.01-cache-2.11-cpan-5a3173703d6 )