class MARC::DataField

MARC records contain data fields, each of which has a tag, indicators and subfields. Tags for data fields must are all three-character tags that are not control fields (generally, any numeric tag greater than 009).

Accessor attributes: tag, indicator1, indicator2

DataField mixes in Enumerable to enable access to it’s constituent Subfield objects. For instance, if you have a DataField representing a 856 tag, and want to find all ‘z’ subfields:

subfield_z = field.find_all {|subfield| subfield.code == 'z'}

Also, the accessor ‘subfields’ is an array of MARC::Subfield objects which can be accessed or modified by the client directly if neccesary.

Attributes

indicator1[RW]

The first indicator

indicator2[RW]

The second indicator

subfields[RW]

A list of MARC::Subfield objects

tag[RW]

The tag for the field

Public Class Methods

new(tag, i1 = " ", i2 = " ", *subfields) click to toggle source

Create a new field with tag, indicators and subfields. Subfields are passed in as comma separated list of MARC::Subfield objects,

field = MARC::DataField.new('245','0','0',
  MARC::Subfield.new('a', 'Consilience :'),
  MARC::Subfield.new('b', 'the unity of knowledge '),
  MARC::Subfield.new('c', 'by Edward O. Wilson.'))

or using a shorthand:

field = MARC::DataField.new('245','0','0',
  ['a', 'Consilience :'],['b','the unity of knowledge '],
  ['c', 'by Edward O. Wilson.'] )
# File lib/marc/datafield.rb, line 49
def initialize(tag, i1 = " ", i2 = " ", *subfields)
  # if the tag is less than 3 characters long and
  # the string is all numeric then we pad with zeros
  @tag = if (tag.length < 3) && (/^[0-9]+$/ =~ tag)
    "%03d" % tag
  else
    tag
  end
  # can't allow nil to be passed in or else it'll
  # screw us up later when we try to encode
  @indicator1 = i1.nil? ? " " : i1
  @indicator2 = i2.nil? ? " " : i2

  @subfields = []

  # allows MARC::Subfield objects to be passed directly
  # or a shorthand of ['a','Foo'], ['b','Bar']
  subfields.each do |subfield|
    case subfield
    when MARC::Subfield
      @subfields.push(subfield)
    when Array
      if subfield.length > 2
        raise MARC::Exception.new,
          "arrays must only have 2 elements: " + subfield.to_s
      end
      @subfields.push(
        MARC::Subfield.new(subfield[0], subfield[1])
      )
    else
      raise MARC::Exception.new,
        "invalid subfield type #{subfield.class}"
    end
  end
end

Public Instance Methods

==(other) click to toggle source

Two fields are equal if their tag, indicators and subfields are all equal.

# File lib/marc/datafield.rb, line 168
def ==(other)
  if !other.is_a?(DataField)
    return false
  end
  if @tag != other.tag
    return false
  elsif @indicator1 != other.indicator1
    return false
  elsif @indicator2 != other.indicator2
    return false
  elsif @subfields != other.subfields
    return false
  end
  true
end
=~(regex) click to toggle source

To support regex matching with fields

if field =~ /Huckleberry/ ...
# File lib/marc/datafield.rb, line 188
def =~(regex)
  to_s =~ regex
end
[](code) click to toggle source

You can lookup subfields with this shorthand. Note it will return a string and not a MARC::Subfield object.

subfield = field['a']
# File lib/marc/datafield.rb, line 153
def [](code)
  subfield = find { |s| s.code == code }
  return subfield.value if subfield
  nil
end
append(subfield) click to toggle source

Add a subfield (MARC::Subfield) to the field

field.append(MARC::Subfield.new('a','Dave Thomas'))
# File lib/marc/datafield.rb, line 132
def append(subfield)
  @subfields.push(subfield)
end
codes(dedup = true) click to toggle source
# File lib/marc/datafield.rb, line 159
def codes(dedup = true)
  codes = []
  @subfields.each { |s| codes << s.code }
  dedup ? codes.uniq : codes
end
each() { |subfield| ... } click to toggle source

You can iterate through the subfields in a Field:

field.each {|s| print s}
# File lib/marc/datafield.rb, line 139
def each
  subfields.each do |subfield|
    yield subfield
  end
end
errors() click to toggle source

Returns an array of validation errors

# File lib/marc/datafield.rb, line 91
def errors
  messages = []

  # must use MARC::ControlField for tags < 010 or
  # those in MARC::ControlField#extra_control_fields

  if MARC::ControlField.control_tag?(@tag)
    messages << "MARC::DataField objects can't have ControlField tag '" + @tag + "'"
  end

  messages
end
to_hash() click to toggle source

Turn the variable field and subfields into a hash for MARC-in-JSON

# File lib/marc/datafield.rb, line 121
def to_hash
  field_hash = {@tag => {"ind1" => @indicator1, "ind2" => @indicator2, "subfields" => []}}
  each do |subfield|
    field_hash[@tag]["subfields"] << {subfield.code => subfield.value}
  end
  field_hash
end
to_marchash() click to toggle source

Turn into a marc-hash structure

# File lib/marc/datafield.rb, line 115
def to_marchash
  [@tag, @indicator1, @indicator2, @subfields.map { |sf| [sf.code, sf.value] }]
end
to_s() click to toggle source

Returns a string representation of the field such as:

245 00 $aConsilience :$bthe unity of knowledge $cby Edward O. Wilson.
# File lib/marc/datafield.rb, line 107
def to_s
  str = "#{tag} "
  str += "#{indicator1}#{indicator2} "
  @subfields.each { |subfield| str += subfield.to_s }
  str
end
valid?() click to toggle source

Returns true if there are no error messages associated with the field

# File lib/marc/datafield.rb, line 86
def valid?
  errors.none?
end
value() click to toggle source

to get the field as a string, without the tag and indicators useful in situations where you want a legible version of the field

print record.value

# File lib/marc/datafield.rb, line 197
def value
  (@subfields.map { |s| s.value }.join "")
end