Class: Libis::Metadata::VarField
- Inherits:
-
Object
- Object
- Libis::Metadata::VarField
- Defined in:
- lib/libis/metadata/var_field.rb
Overview
Helper class implementing a variable field for MARC
Instance Attribute Summary collapse
-
#ind1 ⇒ Object
readonly
Returns the value of attribute ind1.
-
#ind2 ⇒ Object
readonly
Returns the value of attribute ind2.
-
#subfield_data ⇒ Object
readonly
Returns the value of attribute subfield_data.
-
#tag ⇒ Object
readonly
Returns the value of attribute tag.
Instance Method Summary collapse
-
#add_subfield(name, value) ⇒ Object
Add subfield to variable field.
-
#dump ⇒ String
dump the contents.
-
#dump_line ⇒ String
dump the contents.
-
#initialize(tag, ind1, ind2) ⇒ VarField
constructor
Create new variable field with given tag and indicators.
-
#keys ⇒ Array
list the subfield codes.
-
#match(criteria) ⇒ String
check if the current VarField matches the given subfield criteria.
-
#subfield(s) ⇒ String
get the first (or only) subfield value for the given code.
-
#subfield_array(s) ⇒ Array
get a list of all subfield values for a given code.
-
#subfields(s) ⇒ Array
get a list of the first subfield values for all the codes in the given string.
-
#subfields_array(s) ⇒ Array
get a list of all the subfield values for all the codes in the given string.
Constructor Details
#initialize(tag, ind1, ind2) ⇒ VarField
Create new variable field with given tag and indicators
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
#ind1 ⇒ Object (readonly)
Returns the value of attribute ind1.
14 15 16 |
# File 'lib/libis/metadata/var_field.rb', line 14 def ind1 @ind1 end |
#ind2 ⇒ Object (readonly)
Returns the value of attribute ind2.
15 16 17 |
# File 'lib/libis/metadata/var_field.rb', line 15 def ind2 @ind2 end |
#subfield_data ⇒ Object (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 |
#tag ⇒ Object (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
32 33 34 |
# File 'lib/libis/metadata/var_field.rb', line 32 def add_subfield(name, value) @subfield_data[name] << value end |
#dump ⇒ String
dump the contents
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_line ⇒ String
dump the contents
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 |
#keys ⇒ Array
list the 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
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
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
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)
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)
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 |