I did some research. It is possible to do this. Some people may consider the resulting code a bit bizarre, I am sure. But it is do-able.
Using the Want.pm module we can gather information about several different contexts in which the code is executing. We add a flag to the MARC::Record object telling what is going on. And re-route. At the top of MARC::Record we add: use Want; We modify sub field: sub field { my $self = shift; my @specs = @_; if ( want('REF') eq 'OBJECT') { $self->{_field_subfield} = [EMAIL PROTECTED]; return $self; } ... the rest as before ... } Now when we are returning $self instead of a MARC::Field object, it is MARC::Record->subfield() getting invoked. We modify there as well: sub subfield { my $self = shift; my @fields; if ($self->{_field_subfield}) { my $tags = $self->{_field_subfield}; undef $self->{_field_subfield}; @fields = $self->field(@$tags); } else { my $tag = shift; @fields = $self->field($tag); } my $subfield = shift; return unless @fields; my @subfields; for my $field (@fields) { my $subfield_data = $field->subfield($subfield); if ($subfield_data) { push(@subfields,$subfield_data) ; last unless wantarray; } } return wantarray ? @subfields : $subfields[0]; } # subfield() And, sim-sala-bim, we can write code like this: #!/usr/local/bin/perl use strict; use diagnostics; use warnings; use MARC::Record; open(IN,'1_marc_record.mrc') || die; my $subfield; my @subfields; my $MARC = <IN>; my $record = MARC::Record->new_from_usmarc($MARC); $subfield = $record->field('035')->subfield('a') ; @subfields = $record->field('035')->subfield('a') ; # or even @subfields = $record->field('035','100')->subfield('a') ; print "subfield=$subfield\n"; print "[EMAIL PROTECTED]"; # as we did some extra work to the subfield() method we can also do this $subfield = $record->subfield('035','a'); @subfields = $record->subfield('035','a'); print "subfield=$subfield\n"; print "[EMAIL PROTECTED]"; __END__ And it shouldn't even break any existing code. Leif -----Ursprungligt meddelande----- Från: Leif Andersson Skickat: den 7 november 2003 02:46 Till: Paul Hoffman Kopia: [EMAIL PROTECTED] Ämne: Re: Return values from MARC::Record It seems you are right. That's a pity. Not so much because of the error checking. But I was also hoping there was something to be done to situations like this: Assume we have a record with two 035 fields 035 -- $91234567 035 -- $a(XX)12345678 Now, this code will get the 035 $9 subfield: $subfield = eval { $record->field('035')->subfield('9') }; @subfields = eval { $record->field('035')->subfield('9') }; But this it will fail getting 035 $a $subfield = eval { $record->field('035')->subfield('a') }; @subfields = eval { $record->field('035')->subfield('a') }; Leif -----Ursprungligt meddelande----- Från: Paul Hoffman [mailto:[EMAIL PROTECTED] Skickat: den 6 november 2003 22:30 Till: Leif Andersson Kopia: [EMAIL PROTECTED] Ämne: Re: Return values from MARC::Record On Thursday, November 6, 2003, at 01:14 PM, Leif Andersson wrote: > With the same BAD record we try $subfield = eval { > $record->field($tag)->subfield($sub) } > This is the only case where we have to put the code in eval. > Should MARC:: take care of the eval for us? I am beginning to think so. No, it can't. Just add your own error checking, something like this for example: my $field = $record->field($tag) || die "No tag '$tag' in record"; $subfield = $field->subfield($sub); MARC::Record::field has no way of knowing that your code will invoke the method 'subfield' on the value it returns. You could also do it like this if you want to keep things concise: $subfield = ($record->field($tag) || die "No tag '$tag' in record")->subfield($sub); But that's getting a wee bit obfuscated. Paul. -- Paul Hoffman :: Taubman Medical Library :: Univ. of Michigan [EMAIL PROTECTED] :: [EMAIL PROTECTED] :: http://www.nkuitse.com/