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

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

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


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/marc/datafield.rb', line 93

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 = SubfieldMap.new

  # 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

- (Object) indicator1

The first indicator



69
70
71
# File 'lib/marc/datafield.rb', line 69

def indicator1
  @indicator1
end

- (Object) indicator2

The second indicator



72
73
74
# File 'lib/marc/datafield.rb', line 72

def indicator2
  @indicator2
end

- (Object) tag

The tag for the field



66
67
68
# File 'lib/marc/datafield.rb', line 66

def tag
  @tag
end

Instance Method Details

- (Object) ==(other)

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



219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/marc/datafield.rb', line 219

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

- (Object) =~(regex)

To support regex matching with fields

  if field =~ /Huckleberry/ ...


237
238
239
# File 'lib/marc/datafield.rb', line 237

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

- (Object) [](code)

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

  subfield = field['a']


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

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

- (Object) append(subfield)

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

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


164
165
166
# File 'lib/marc/datafield.rb', line 164

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

- (Object) codes



212
213
214
# File 'lib/marc/datafield.rb', line 212

def codes
  @subfields.code_list
end

- (Object) each

You can iterate through the subfields in a Field:

  field.each {|s| print s}


173
174
175
176
177
# File 'lib/marc/datafield.rb', line 173

def each
  for subfield in subfields
    yield subfield
  end
end

- (Object) each_by_code(filter)



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

def each_by_code(filter)
  @subfields.each_by_code(filter)
end

- (Object) subfields(filter = nil)



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/marc/datafield.rb', line 193

def subfields(filter=nil)
  return @subfields unless filter
  @subfields.reindex unless subfields.in_sync?
  subflds = []
  if filter.is_a?(String) && @subfields.codes[filter]
    @subfields.codes[filter].each do |idx|
      subflds << @subfields[idx]
    end
  elsif filter.is_a?(Array) || filter.is_a?(Range)
    filter.each do |code|
      next unless @subfields.codes[code]
      @subfields.codes[code].each do |idx|
        subflds << @subfields[idx]
      end
    end
  end
  subflds
end

- (Object) to_hash

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



153
154
155
156
157
158
159
# File 'lib/marc/datafield.rb', line 153

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

- (Object) to_marchash

Turn into a marc-hash structure



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

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

- (Object) to_s

Returns a string representation of the field such as:

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


139
140
141
142
143
144
# File 'lib/marc/datafield.rb', line 139

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

- (Object) value

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[‘245’].value



247
248
249
# File 'lib/marc/datafield.rb', line 247

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