MARC::Record(3pm)
๐ MARC::Record ๐
okay bestie, sit DOWN. this is MARC::Record from the User Contributed Perl Documentation, section 3pm, and it's literally the module that lets you handle MARC records as objects. we're gonna go through every last bit of it together, no skimming, no skipping, periodt. ๐โจ
๐ VERSION ๐
Version 2.0.7. that's the one, that's the girl. ๐
๐ฆ DESCRIPTION ๐ฆ
So like โ this is the module for handling MARC records as objects. that's the whole vibe. ๐ซถ
And the file-handling stuff? Not here, babe. That lives in MARC::File::*. different department, different floor, iykyk.
๐ญ ERROR HANDLING ๐ญ
- any error that gets generated? it's stored in
$MARC::Record::ERROR. that's where you go looking when something's off. ๐ - warnings are a whole different energy โ they're kept with the record, and you get at them with the
warnings()method.
๐ฑ CONSTRUCTORS ๐ฑ
โจ new()
The base constructor for the class, and honestly? she gives nothing. she just returns a completely empty record. no fields, no data, a blank canvas, main character before the glow-up. ๐
So like, to get real data in there you've got two options:
- populate it yourself with fields, or
- use one of the
MARC::File::*modules to read from a file.
โจ new_from_usmarc( $marcblob [, \&filter_func($tagno,$tagdata)] )
This one's a wrapper around MARC::File::USMARC::decode(), and the reason it exists is compatibility with older versions of MARC::Record. it's giving "keeping the old friendships alive". ๐ฅน
The wanted_func() is optional. See MARC::File::USMARC::decode for details โ that's where the tea is.
๐ COMMON FIELD RETRIEVAL METHODS ๐
Okay so here's a lil cluster of convenience methods for the data fields everybody's always grabbing. Super important: each of these returns strings, not MARC::Field objects. ๐ง
And if the appropriate field or subfield isn't found, you get back empty strings. which is different from the field() / subfield() methods, those ones hand you back undef when something's missing. The assumption (and it's a fair one) is that these convenience methods are for quick & dirty reports where you do NOT want to be messing around checking if something is undef. respect. ๐
Also also โ no punctuation cleanup is done. none. zero. if the 245a is "Programming Perl / ", then that's exactly what you get back, trailing slash and all. not "Programming Perl". you want it cleaned, that's a you problem, bestie. ๐
โจ title()
Returns the title from the 245 tag.
โจ title_proper()
Returns the title proper from the 245 tag, subfields a, n and p.
โจ author()
Returns the author from the 100, 110 or 111 tag.
โจ edition()
Returns the edition from the 250 tag, subfield a.
โจ publication_date()
Returns the publication date from the 260 tag, subfield c.
๐ FIELD & SUBFIELD ACCESS METHODS ๐
โจ fields()
Returns a list of all the fields in the record. The list contains a MARC::Field object for each field in the record. the whole squad, assembled. ๐ฅ
โจ field( tagspec(s) )
Returns a list of tags that match the field specifier, or an empty list if nothing matched.
In scalar context, it returns the first matching tag, or undef if nothing matched.
The field specifier can be:
- a simple number, i.e.
245, or - the
.notation of wildcarding โ i.e. subject tags are6...
โจ subfield( $tag, $subfield )
Shortcut method for getting just a subfield for a tag. These two are equivalent, like literally the same thing, pick your fighter:
my $title = $marc->field('245')->subfield("a");
my $title = $marc->subfield('245',"a");
If either the field or the subfield can't be found, undef is returned. no field, no subfield, no data, no drama. ๐ญ
โจ append_fields( @fields )
Appends the field specified by $field to the end of the record. @fields need to be MARC::Field objects. no imposters. ๐
my $field = MARC::Field->new('590','','','a' => 'My local note.');
$record->append_fields($field);
Returns the number of fields appended. count 'em.
โจ insert_fields_before( $before_field, @new_fields )
Inserts the field specified by $new_field before the field $before_field.
Returns the number of fields inserted, or undef on failures. Both $before_field and all @new_fields need to be MARC::Field objects. If they are not, an exception will be thrown. so like, don't try it. ๐
my $before_field = $record->field('260');
my $new_field = MARC::Field->new('250','','','a' => '2nd ed.');
$record->insert_fields_before($before_field,$new_field);
โจ insert_fields_after( $after_field, @new_fields )
Identical to insert_fields_before(), except the fields are added after $after_field. remember bestie: $after_field and any new fields must be valid MARC::Field objects or else an exception will be thrown. same rules, other direction. ๐
โจ insert_fields_ordered( @new_fields )
Will insert fields in strictly numerical order. So a 008 will be filed after a 001 field. neat, tidy, organized โ the good girl of field insertion. โจ
See insert_grouped_field() for an additional ordering if you want a different flavor.
โจ insert_grouped_field( $field )
Will insert the specified MARC::Field object into the record in grouped order, and return true (1) on success, and false (undef) on failure.
my $field = MARC::Field->new( '510', 'Indexed by Google.' );
$record->insert_grouped_field( $field );
So for example, if a 650 field is inserted with insert_grouped_field(), it will be inserted at the end of the 6XX group of tags. and here's the lore: after discussion, most people wanted the ability to add a new field to the end of the hundred group where it belonged. And the reason is that according to the MARC format, fields within a record are supposed to be grouped by block (hundred groups). which means fields may not necessarily be in tag order. so like, chill, it's on purpose. ๐ซถ
โจ delete_fields( $field )
Deletes a given list of MARC::Field objects from the record.
# delete all note fields
my @notes = $record->field('5..');
$record->delete_fields(@notes);
delete_fields() will return the number of fields that were deleted. byeeee ๐
โจ delete_field()
Same thing as delete_fields() but only expects a single MARC::Field to be passed in. Mainly here for backwards compatibility. the older sibling who still shows up. ๐ฅน
โจ as_usmarc()
This is a wrapper around MARC::File::USMARC::encode() for compatibility with older versions of MARC::Record.
โจ as_formatted()
Returns a pretty string for printing in a MARC dump. pretty as in formatting pretty, not pretty-pretty, but honestly? both. ๐
โจ leader()
Returns the leader for the record. Sets the leader if text is defined. No error checking is done on the validity of the leader. so if you hand it nonsense, it will literally just hold the nonsense. she doesn't check IDs at the door. ๐
โจ encoding()
A method for getting/setting the encoding for a record.
The encoding for a record is determined by position 09 in the leader:
- blank โ
MARC-8encoding 'a'โ UCS/Unicode
encoding() will return a string, either 'MARC-8' or 'UTF-8', appropriately.
If you want to set the encoding for a MARC::Record object you can use the string values:
$record->encoding( 'UTF-8' );
NOTE:MARC::Recordobjects created from scratch have a default encoding ofMARC-8, which has been the standard for years... but many online catlogs and record vendors are migrating toUTF-8.
WARNING: โ ๏ธ you should be sure your record really does contain valid UTF-8 data when you manually set the encoding. don't be out here lying to your own record, bestie. fr fr.
โจ set_leader_lengths( $reclen, $baseaddr )
Internal function for updating the leader's length and base address. like, internal internal. you didn't see this. ๐
โจ clone()
The clone() method makes a copy of an existing MARC record and returns the new version.
Note that you cannot just say:
my $newmarc = $oldmarc;
Because that just makes a copy of the reference, not a new object. sneaky. ๐ญ You must use the clone() method like so:
my $newmarc = $oldmarc->clone;
You can also specify field specs to filter down only a certain subset of fields. For instance, if you only wanted the title and ISBN tags from a record, you could do this:
my $small_marc = $marc->clone( 245, '020' );
And the order of the fields is preserved as it was in the original record. first come, first served. โจ
โจ warnings()
Returns the warnings (as a list) that were created when the record was read. These are things like "Invalid indicators converted to blanks".
my @warnings = $record->warnings();
The warnings are items that you might be interested in, or might not. It depends on how stringently you're checking data. If you're doing some grunt data analysis, you probably don't care. ๐ฅฑ
side effect alert: a side effect of calling warnings() is that the warning buffer will be cleared. so read 'em and they're gone. take a screenshot, bestie. ๐ธ
โจ add_fields()
okay so add_fields() is now deprecated, and users are encouraged to use append_fields(), insert_fields_after(), and insert_fields_before() since they do what you want, probably. It is still here though, for backwards compatibility. she's retired but she still answers the phone. ๐ซถ
add_fields() adds MARC::Field objects to the end of the list. Returns the number of fields added, or undef if there was an error.
There are three ways of calling add_fields() to add data to the record.
- Create a
MARC::Fieldobject and add it โ the DIY approach ๐
my $author = MARC::Field->new(
100, "1", " ", a => "Arnosky, Jim."
);
$marc->add_fields( $author );
- Add the data fields directly, and let
add_fields()take care of the objectifying โ the low-effort queen approach โจ
$marc->add_fields(
245, "1", "0",
a => "Raccoons and ripe corn /",
c => "Jim Arnosky.",
);
- Same as #2 above, but pass multiple fields of data in anonymous lists โ the bulk order approach ๐๏ธ
$marc->add_fields(
[ 250, " ", " ", a => "1st ed." ],
[ 650, "1", " ", a => "Raccoons." ],
);
๐ฎ DESIGN NOTES ๐ฎ
A brief discussion of why MARC::Record is done the way it is. grab a snack, this is the lore section. ๐
- It's built for quick prototyping
One of the areas Perl excels is in allowing the programmer to create easy solutions quickly. MARC::Record is designed along those same lines. You want a program to dump all the 6XX tags in a file? MARC::Record is your friend. ๐ซถ
- It's built for extensibility
Currently, I'm using MARC::Record for analyzing bibliographic data, but who knows what might happen in the future? MARC::Record needs to be just as adept at authority data, too. ๐
- It's designed around accessor methods
I use method calls everywhere, and I expect calling programs to do the same, rather than accessing internal data directly. If you access an object's hash fields on your own, future releases may break your code. โ ๏ธ so like, hands off the internals, bestie.
- It's not built for speed
One of the tradeoffs in using accessor methods is some overhead in the method calls. Is this slow? I don't know, I haven't measured. I would suggest that if you're a cycle junkie that you use Benchmark.pm to check to see where your bottlenecks are, and then decide if MARC::Record is for you. ๐โ๏ธ
๐ง RELATED MODULES ๐ง
MARC::Field, MARC::Batch, MARC::File::XML, MARC::Charset, MARC::Lint
the whole friend group. ๐
๐ธ SEE ALSO ๐ธ
- perl4lib (
http://perl4lib.perl.org/)
A mailing list devoted to the use of Perl in libraries. ๐
- Library Of Congress MARC pages (
http://www.loc.gov/marc/)
The definitive source for all things MARC. the mothership. ๐
- Understanding MARC Bibliographic (
http://lcweb.loc.gov/marc/umb/)
Online version of the free booklet. An excellent overview of the MARC format. Essential. like, required reading, no cap.
- Tag Of The Month (
http://www.follettsoftware.com/sub/tag_of_the_month/)
Follett Software Company's (http://www.fsc.follett.com/) monthly discussion of various MARC tags. ๐๏ธ
๐ TODO ๐
- Incorporate
MARC.pmin the distribution.
Combine MARC.pm and MARC::* into one distribution. one big happy family. ๐ซถ
- Podify
MARC.pm - Allow regexes across the entire tag
Imagine something like this:
my @sears_headings = $marc->tag_grep( qr/Sears/ );
(from Mike O'Regan)
- Insert a field in an arbitrary place in the record
- Modifying an existing field
bestie this is only part 1, there's more where that came from โ don't wander off ๐ฆ
๐ BUGS, WISHES AND CORRESPONDENCE ๐
okay so bestie, if something's broken or you just wanna chat, email me at mrylander@gmail.com and I'll help as best I can ๐ I am always here for bugs, suggestions and patches, no gatekeeping, we love feedback in this house.
But ngl, if you want info fast and want to vibe with actual humans, the perl4lib mailing list is literally the move. Head to http://perl4lib.perl.org for the deets on the list plus other genuinely helpful MARC info โจ
Also! The MARC::Record dev team runs on the RT bug tracking system at http://rt.cpan.org. So if your email is about a bug or a suggestion, pleeease report it through RT instead โ it's a huge help for the team and you'll get notified as things get fixed or updated ๐ซถ (main character behaviour, honestly).
And if the website is giving you the ick, no stress, just send your bug to bug-MARC-Record@rt.cpan.org ๐
๐ IDEAS ๐
Ideas are things that have been considered but literally nobody has actually asked for yet. (Yes this is a real section. It's giving wishlist energy ๐)
- Create multiple output formats.
These could be ASCII or MarcMaker.
๐ LICENSE ๐
This code may be distributed under the same terms as Perl itself. periodt.
Please note that these modules are not products of or supported by the employers of the various contributors to the code. ๐
๐ AUTHORS ๐
- Andy Lester
- Mike O'Regan
- Ed Summers
- Mike Rylander
- Galen Charlton
and that's a wrap, bestie ๐ this page is from perl v5.36.0, dated 2022-10-13, and yes it's MARC::Record(3pm) โ go forth and catalogue, you absolute icon ๐ธโจ๐ฆ
๐ฆ where this page comes from
- ubuntu noble: libmarc-record-perl 2.0.7-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libmarc-record-perl 2.0.7-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libmarc-record-perl 2.0.7-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms