Class: Libis::Metadata::VarField

Inherits:
Object
  • Object
show all
Defined in:
lib/libis/metadata/var_field.rb

Overview

Helper class implementing a variable field for MARC

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag, ind1, ind2) ⇒ VarField

Create new variable field with given tag and indicators

Parameters:

  • tag (String)

    tag

  • ind1 (String)

    first indicator. nil will be translated into empty string.

  • ind2 (String)

    second indicator. nil will be translated into empty string.



22
23
24
25
26
27
# File 'lib/libis/metadata/var_field.rb', line 22

def initialize(tag, ind1, ind2)
  @tag = tag
  @ind1 = ind1 || ''
  @ind2 = ind2 || ''
  @subfield_data = Hash.new {|h, k| h[k] = Array.new}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (private)

implementation for methods for retrieving subfield values

The methods start with a single character: the operation ‘f’ for retrieving only the first occurence of the subfield ‘a’ for retrieving all the subfield values for each of the given subfields if omitted, ‘f’ is assumed

Then a ‘_’ acts as a subdivider between the operation and the subfield(s). It must always be present, even if the operation is omitted.

The last past is a sequence of subfield codes that should be used for selecting the values. The order in which the subfields are listed is respected in the resulting array of values.

Examples:

t = VarField.new('100', '', '',
                 { 'a' => %w'Name NickName',
                   'b' => %w'LastName MaidenName',
                   'c' => %w'eMail',
                   '1' => %w'Age',
                   '9' => %w'Score'})

# >> 100##$aName$aNickName$bLastName$bMaidenName$ceMail$1Age$9Score <<

t._1ab => ['Age', 'Name', 'LastName']
# equivalent to: t.f_1av or t.fields('1ab')

t.a_9ab => ['Score', 'Name', 'NickName', 'LastName', 'MaidenName']
# equivalent to: t.fields_array('9ab')

Note that it is not possible to use a fieldspec for the sequence of subfield codes. Spaces and ‘-’ are not allowed in method calls. If you want this, use the #subfield(s) and #subfield(s)_array methods.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/libis/metadata/var_field.rb', line 208

def method_missing(name, *args)
  operation, subfields = name.to_s.split('_')
  assert(subfields.size > 0, 'need to specify at least one subfield')
  operation = 'f' if operation.empty?
  # convert subfield list to fieldspec
  subfields = subfields.split('').join(' ')
  case operation
  when 'f'
    if subfields.size > 1
      operation = :subfields
    else
      operation = :subfield
    end
  when 'a'
    if subfields.size > 1
      operation = :subfields_array
    else
      operation = :subfield_array
    end
  else
    throw "Unknown method invocation: '#{name}' with: #{args}"
  end
  send(operation, subfields)
end

Instance Attribute Details

#ind1Object (readonly)

Returns the value of attribute ind1.



14
15
16
# File 'lib/libis/metadata/var_field.rb', line 14

def ind1
  @ind1
end

#ind2Object (readonly)

Returns the value of attribute ind2.



15
16
17
# File 'lib/libis/metadata/var_field.rb', line 15

def ind2
  @ind2
end

#subfield_dataObject (readonly)

Returns the value of attribute subfield_data.



16
17
18
# File 'lib/libis/metadata/var_field.rb', line 16

def subfield_data
  @subfield_data
end

#tagObject (readonly)

Returns the value of attribute tag.



13
14
15
# File 'lib/libis/metadata/var_field.rb', line 13

def tag
  @tag
end

Instance Method Details

#add_subfield(name, value) ⇒ Object

Add subfield to variable field

Parameters:

  • name (String)

    subfield indicator without ‘$’

  • value (String)

    content of the subfield



32
33
34
# File 'lib/libis/metadata/var_field.rb', line 32

def add_subfield(name, value)
  @subfield_data[name] << value
end

#dumpString

dump the contents

Returns:

  • (String)

    debug output to inspect the contents of the VarField



39
40
41
42
43
# File 'lib/libis/metadata/var_field.rb', line 39

def dump
  output = "#{@tag}:#{@ind1}:#{@ind2}:\n"
  @subfield_data.each {|s, t| output += "\t#{s}:#{t}\n"}
  output
end

#dump_lineString

dump the contents

Returns:

  • (String)

    debug output to inspect the contents of the VarField - Single line version



48
49
50
51
52
# File 'lib/libis/metadata/var_field.rb', line 48

def dump_line
  output = "#{@tag}:#{@ind1}:#{@ind2}:"
  @subfield_data.each {|s, t| output += "$#{s}#{t}"}
  output
end

#keysArray

list the subfield codes

Returns:

  • (Array)

    a list of all subfield codes



57
58
59
# File 'lib/libis/metadata/var_field.rb', line 57

def keys
  @subfield_data.keys
end

#match(criteria) ⇒ String

check if the current VarField matches the given subfield criteria.

The subfield criteria consists of groups of characters. At least one of these groups should match for the test to succeed Within the group sets of codes may be divided by a hyphen (-). The first set of codes must all be present; the second set of codes must all not be present. Either set may be empty.

Examples:

'ab'      matches '$a...$b...'            => ['ab']
                  '$a...$b...$c...'       => ['ab']
          but not '$a...'                 => nil      # ($b missing)
                  '$b...'                 => nil      # ($a missing)
'a b'     matches '$a...'                 => ['a']
                  '$b...'                 => ['b']
                  '$a...$b...'            => ['a', 'b']
                  '$a...$b...$c...'       => ['a', 'b']
          but not '$c...'                 => nil      # ($a or $b must be present)
'abc-d'   matches '$a..,$b...$c...'       => ['abc-d']
                  '$a..,$b...$c...$e...'  => ['abc-d']
          but not '$a...$b...$e...'       => nil      # ($c missing)
                  '$a...$b...$c...$d...'  => nil      # ($d should not be present)
'a-b b-a' matches '$a...'                 => ['a-b']
                  '$a...$c...'            => ['a-b']
                  '$b...'                 => ['b-a']
                  '$b...$c...'            => ['b-a']
          but not '$a...$b...'            => nil
'a-b c-d' matches '$a...'                 => ['a-b']
                  '$a...$c...'            => ['a-b', 'c-d']
                  '$a...$b...$c...'       => ['c-d']
                  '$b...$c...'            => ['c-d']
          but not '$a...$b...'            => nil
                  '$c...$d...'            => nil
                  '$b...$c...$d...'       => nil
                  '$a...$b...$c...$d...'  => nil

Parameters:

  • criteria (String)

    subfield criteria: sequence of alternative set of subfield codes that should-shouldn’t be present

Returns:

  • (String)

    The matching part(s) of the criteria or nil if no match



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/libis/metadata/var_field.rb', line 139

def match(criteria)
  begin
    parser = Libis::Metadata::Parser::SubfieldCriteriaParser.new
    tree = parser.parse(criteria)
    return [] if tree.is_a? String
    tree = [tree] unless tree.is_a? Array
    result = tree.map do |selection|
      next unless parser.match_selection(selection, keys)
      parser.selection_to_s(selection)
    end.compact
    return nil if result.empty?
    result
  rescue Parslet::ParseFailed => failure
    failure.cause.set_label(criteria)
    raise failure
  end
end

#subfield(s) ⇒ String

get the first (or only) subfield value for the given code

Parameters:

  • s (Character)

    the subfield code

Returns:

  • (String)

    the first or only entry of a subfield or nil if not present



65
66
67
# File 'lib/libis/metadata/var_field.rb', line 65

def subfield(s)
  subfield_array(s).first
end

#subfield_array(s) ⇒ Array

get a list of all subfield values for a given code

Parameters:

  • s (Character)

    the subfield code

Returns:

  • (Array)

    all the entries of a repeatable subfield



73
74
75
76
# File 'lib/libis/metadata/var_field.rb', line 73

def subfield_array(s)
  assert(s.is_a?(String) && (s =~ /^[\da-z]$/) == 0, 'method expects a lower case alphanumerical char')
  @subfield_data.has_key?(s) ? @subfield_data[s].dup : []
end

#subfields(s) ⇒ Array

get a list of the first subfield values for all the codes in the given string

The subfield codes are cleaned (see criteria_to_array)

Parameters:

  • s (String)

    subfield code specification (see match)

Returns:

  • (Array)

    list of the first or only entries of all subfield codes in the input string



84
85
86
87
88
# File 'lib/libis/metadata/var_field.rb', line 84

def subfields(s)
  assert(s.is_a?(String), 'method expects a string')
  return [] unless (match_array = match(s))
  criteria_to_array(match_array.join(' ')).collect {|i| send(:subfield, i)}.flatten.compact
end

#subfields_array(s) ⇒ Array

get a list of all the subfield values for all the codes in the given string

The subfield codes are cleaned (see criteria_to_array)

Parameters:

  • s (String)

    subfield code criteria (see match)

Returns:

  • (Array)

    list of the all the entries of all subfield codes in the input string



97
98
99
100
101
# File 'lib/libis/metadata/var_field.rb', line 97

def subfields_array(s)
  assert(s.is_a?(String), 'method expects a string')
  return [] unless (match_array = match(s))
  criteria_to_array(match_array.join(' ')).collect {|i| send(:subfield_array, i)}.flatten.compact
end