Class: MARC::DataField

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/marc/datafield.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag, i1 = ' ', i2 = ' ', *subfields) ⇒ DataField

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.'] )


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/marc/datafield.rb', line 50

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
  if tag.length < 3 and /^[0-9]+$/ =~ tag
    @tag = "%03d" % tag
  else
    @tag = 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 = []

  # must use MARC::ControlField for tags < 010 or
  # those in MARC::ControlField#extra_control_fields
  
  if MARC::ControlField.control_tag?(@tag)
    raise MARC::Exception.new(),
      "MARC::DataField objects can't have ControlField tag '" + @tag + "')"
  end

  # 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

Instance Attribute Details

#indicator1Object

The first indicator



26
27
28
# File 'lib/marc/datafield.rb', line 26

def indicator1
  @indicator1
end

#indicator2Object

The second indicator



29
30
31
# File 'lib/marc/datafield.rb', line 29

def indicator2
  @indicator2
end

#subfieldsObject

A list of MARC::Subfield objects



32
33
34
# File 'lib/marc/datafield.rb', line 32

def subfields
  @subfields
end

#tagObject

The tag for the field



23
24
25
# File 'lib/marc/datafield.rb', line 23

def tag
  @tag
end

Instance Method Details

#==(other) ⇒ Object

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



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/marc/datafield.rb', line 161

def ==(other)
  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
  return true
end

#=~(regex) ⇒ Object

To support regex matching with fields

if field =~ /Huckleberry/ ...


179
180
181
# File 'lib/marc/datafield.rb', line 179

def =~(regex)
  return self.to_s =~ regex
end

#[](code) ⇒ Object

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

subfield = field['a']


145
146
147
148
149
# File 'lib/marc/datafield.rb', line 145

def [](code)
  subfield = self.find {|s| s.code == code}
  return subfield.value if subfield
  return
end

#append(subfield) ⇒ Object

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

field.append(MARC::Subfield.new('a','Dave Thomas'))


122
123
124
# File 'lib/marc/datafield.rb', line 122

def append(subfield)
  @subfields.push(subfield)
end

#codes(dedup = true) ⇒ Object



152
153
154
155
156
# File 'lib/marc/datafield.rb', line 152

def codes(dedup=true)
  codes = []
  @subfields.each {|s| codes << s.code }
  dedup ? codes.uniq : codes
end

#eachObject

You can iterate through the subfields in a Field:

field.each {|s| print s}


131
132
133
134
135
# File 'lib/marc/datafield.rb', line 131

def each
  for subfield in subfields
    yield subfield
  end
end

#to_hashObject

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



111
112
113
114
115
116
117
# File 'lib/marc/datafield.rb', line 111

def to_hash
  field_hash = {@tag=>{'ind1'=>@indicator1,'ind2'=>@indicator2,'subfields'=>[]}}
  self.each do |subfield|
    field_hash[@tag]['subfields'] << {subfield.code=>subfield.value}
  end
  field_hash
end

#to_marchashObject

Turn into a marc-hash structure



105
106
107
# File 'lib/marc/datafield.rb', line 105

def to_marchash
  return [@tag, @indicator1, @indicator2, @subfields.map {|sf| [sf.code, sf.value]} ]
end

#to_sObject

Returns a string representation of the field such as:

245 00 $aConsilience :$bthe unity of knowledge $cby Edward O. Wilson.


97
98
99
100
101
102
# File 'lib/marc/datafield.rb', line 97

def to_s
  str = "#{tag} "
  str += "#{indicator1}#{indicator2} " 
  @subfields.each { |subfield| str += subfield.to_s }
  return str
end

#valueObject

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



189
190
191
# File 'lib/marc/datafield.rb', line 189

def value
  return(@subfields.map {|s| s.value} .join '')
end