Class: Krikri::Parser::ValueArray

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/krikri/parser.rb

Overview

A specialized Array object for containing Parser::Values. Provides methods for accessing and filtering values that can be chained.

Methods defined on this class should return another ValueArray, an Array of literal values (retrieved from Parser::Value#value), or a single literal value.

Uses ‘@top` to track a base node for recovery via `#else`. Methods that return a `ValueArray` should pass `@top` down to the new instance.

Examples:

chaining methods to select values


my_value_array.field('dc:creator', 'foaf:name')
  .match_attribute('first_name').values

conditional recovery. ‘#if` sets `@top`, `#else` rewinds if empty


my_value_array.field('dc:creator', 'foaf:name').if.field('empty:field')
  .else { |vs| vs.field('some:otherField') }

Defined Under Namespace

Classes: InvalidParserValueError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(array = [], top = nil) ⇒ ValueArray

Returns a new instance of ValueArray.

Parameters:

  • array (Array) (defaults to: [])

    an array of values to delegate array operations to

  • top (ValueArray) (defaults to: nil)

    an instance of this class to use as a recovery node in, e.g. ‘#else`. Defaults to `self` if none is passed.



178
179
180
181
# File 'lib/krikri/parser.rb', line 178

def initialize(array = [], top = nil)
  @array = array
  @top = top || self
end

Class Method Details

.build(record) ⇒ ValueArray

Wraps the root node of the given record in this class.

Parameters:

Returns:



401
402
403
# File 'lib/krikri/parser.rb', line 401

def self.build(record)
  new([record.root])
end

Instance Method Details

#<<(value) ⇒ Object

Raises:

See Also:

  • Array#<<


195
196
197
198
199
# File 'lib/krikri/parser.rb', line 195

def <<(value)
  raise InvalidParserValueError unless value.is_a? Value
  @array << value
  value
end

#[]=(index, value) ⇒ Object

Raises:

See Also:

  • Array#[]=


186
187
188
189
190
# File 'lib/krikri/parser.rb', line 186

def []=(index, value)
  raise InvalidParserValueError unless value.is_a? Value
  @array[index] = value
  self
end

#concat(*args, &block) ⇒ ValueArray

Returns:

See Also:

  • Array#concat


204
205
206
# File 'lib/krikri/parser.rb', line 204

def concat(*args, &block)
  self.class.new(@array.concat(*args, &block), @top)
end

#else {|arry| ... } ⇒ ValueArray

Short circuits if ‘self` is not empty, else passes the top of the call chain (`@top`) to the given block.

Examples:

usage with ‘#if`

value_array.if { |arry| arry.field(:a_field) }
  .else { |arry|  arry.field(:alternate_field) }

# use other filters at will
value_array.if.field(:a_field).reject { |v| v == 'SKIP ME' }
  .else { |arry|  arry.field(:alternate_field) }

standalone use; resetting to record root

value_array.field(:a_field).else { |arry| arry.field(:alternate_field) }

Yields:

  • gives ‘@top` if self is empty

Yield Parameters:

Returns:

  • (ValueArray)

    ‘self` unless empty; otherwise the result of the block

Raises:

  • (ArgumentError)


282
283
284
285
286
# File 'lib/krikri/parser.rb', line 282

def else(&block)
  raise ArgumentError, 'No block given for `#else`' unless block_given?
  return self unless self.empty?
  yield @top
end

#field(*args) ⇒ ValueArray

Accesses a given field. Use multiple arguments to travel down the node hierarchy.

Returns:

  • (ValueArray)

    an array containing the nodes available in a particular field.



221
222
223
224
225
226
# File 'lib/krikri/parser.rb', line 221

def field(*args)
  result = self
  args.each { |name| result = result.get_field(name) }

  result
end

#fields(*args) ⇒ ValueArray

Accesses the union of multiple specified fields.

given fields.

Returns:

  • (ValueArray)

    an array containing the nodes available in the



233
234
235
236
237
238
# File 'lib/krikri/parser.rb', line 233

def fields(*args)
  results = args.map do |f|
    field(*Array(f))
  end
  self.class.new(results.flatten, @top)
end

#first_value(*args) ⇒ ValueArray

Retrieves the first element of a ValueArray. Uses an optional argument to specify how many items to return. By design, it behaves similarly to Array#first, but it intentionally doesn’t override it.

Returns:

  • (ValueArray)

    a Krikri::Parser::ValueArray for first n elements



294
295
296
297
# File 'lib/krikri/parser.rb', line 294

def first_value(*args)
  return self.class.new(@array.first(*args)) unless args.empty?
  self.class.new([@array.first].compact, @top)
end

#flatten(*args, &block) ⇒ ValueArray

Returns:

See Also:

  • Array#concat


314
315
316
# File 'lib/krikri/parser.rb', line 314

def flatten(*args, &block)
  self.class.new(@array.flatten(*args, &block), @top)
end

#if {|arry| ... } ⇒ ValueArray

Sets the top of the call chain to self and returns or yields self

Examples:

with method chain syntax

value_array.if.field(:a_field).else do |arry|
   arry.field(:alternate_field)
end

with block syntax

value_array.if { |arry| arry.field(:a_field) }
  .else { |arry|  arry.field(:alternate_field) }

Yields:

  • gives self

Yield Parameters:

Returns:

  • (ValueArray)

    the result of the block, if given; or self with @top set



256
257
258
259
260
# File 'lib/krikri/parser.rb', line 256

def if(&block)
  @top = self
  return yield self if block_given?
  self
end

#last_value(*args) ⇒ ValueArray

Retrieves the last element of a ValueArray. Uses an optional argument to specify how many items to return. By design, it behaves similarly to Array#last, but it intentionally doesn’t override it.

Returns:

  • (ValueArray)

    a Krikri::Parser::ValueArray for last n elements



305
306
307
308
# File 'lib/krikri/parser.rb', line 305

def last_value(*args)
  return self.class.new(@array.last(*args)) unless args.empty?
  self.class.new([@array.last].compact, @top)
end

#map(*args, &block) ⇒ ValueArray

Wraps the result of Array#map in a ValueArray

Returns:

See Also:

  • Array#map


323
324
325
# File 'lib/krikri/parser.rb', line 323

def map(*args, &block)
  self.class.new(@array.map(*args, &block), @top)
end

#match_attribute(name, other = nil) {|value| ... } ⇒ ValueArray

Returns an array containing nodes for which the specified attribute has a value matching the given attribute name, object, and block.

Examples:

selecting by presence of an attribute; returns all nodes where

`#attribute?(:type)` is true

match_attribute(:type)

selecting by the value of an attribute; returns all nodes with

`#attribute(:type) == other`

match_attribute(:type, other)

selecting by block against an attribute; returns all nodes with

`block.call(attribute(:type))` is true

match_attribute(:type) { |value| value.starts_with? 'blah' }

selecting by block against an attribute; returns all nodes with

`block.call(attribute(:type)) == other` is true

match_attribute(:type, 'moomin') { |value| value.downcase }

Parameters:

  • name (#to_sym)

    an attribute name

  • other (Object) (defaults to: nil)

    an object to check for equality with the values from the given attribute.

Yields:

  • (value)

    yields each value with the attribute in name to the block

Returns:

  • (ValueArray)

    an array containing nodes for which the specified attribute has a value matching the given attribute name, object, and block.



375
376
377
# File 'lib/krikri/parser.rb', line 375

def match_attribute(name, other = nil, &block)
  select(&compare_to_attribute(name, other, &block))
end

#reject(*args, &block) ⇒ ValueArray

Wraps the result of Array#reject in a ValueArray

Returns:

See Also:

  • Array#reject


341
342
343
# File 'lib/krikri/parser.rb', line 341

def reject(*args, &block)
  self.class.new(@array.reject(*args, &block), @top)
end

#reject_attribute(name, other = nil) {|value| ... } ⇒ ValueArray

Returns an array containing nodes for which the specified attribute does not have a value matching the given attribute name, object, and block.

Parameters:

  • name (#to_sym)

    an attribute name

  • other (Object) (defaults to: nil)

    an object to check for equality with the values from the given attribute.

Yields:

  • (value)

    yields each value with the attribute in name to the block

Returns:

  • (ValueArray)

    an array containing nodes for which the specified attribute does not have a value matching the given attribute name, object, and block.

See Also:



392
393
394
# File 'lib/krikri/parser.rb', line 392

def reject_attribute(name, other = nil, &block)
  reject(&compare_to_attribute(name, other, &block))
end

#select(*args, &block) ⇒ ValueArray

Wraps the result of Array#select in a ValueArray

Returns:

See Also:

  • Array#select


332
333
334
# File 'lib/krikri/parser.rb', line 332

def select(*args, &block)
  self.class.new(@array.select(*args, &block), @top)
end

#valuesArray

Returns literal values from the objects in this array.

Returns:

  • (Array)

    literal values from the objects in this array.

See Also:



211
212
213
# File 'lib/krikri/parser.rb', line 211

def values
  @array.map { |v| v.respond_to?(:value) ? v.value : v }
end