Class: RDF::List

Inherits:
Object
  • Object
show all
Includes:
Comparable, Enumerable, Value
Defined in:
lib/rdf/model/list.rb

Overview

An RDF list.

Examples:

Constructing a new list

RDF::List[1, 2, 3]

Since:

  • 0.2.3

Constant Summary collapse

UNSET =

Since:

  • 0.2.3

Object.new.freeze
NIL =

The canonical empty list.

Since:

  • 0.2.3

RDF::List.new(subject: RDF.nil).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Value

#anonymous?, #canonicalize, #canonicalize!, #constant?, #graph?, #inspect!, #invalid?, #iri?, #literal?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #type_error, #uri?, #validate!, #variable?

Methods included from Enumerable

#canonicalize, #canonicalize!, #dump, #each_graph, #each_object, #each_predicate, #each_quad, #each_term, #each_triple, #enum_graph, #enum_object, #enum_predicate, #enum_quad, #enum_statement, #enum_subject, #enum_term, #enum_triple, #graph?, #graph_names, #invalid?, #object?, #objects, #predicate?, #predicates, #project_graph, #quad?, #quads, #statement?, #statements, #subject?, #subjects, #supports?, #term?, #terms, #to_h, #triple?, #triples, #validate!

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Countable

#count, #enum_for

Constructor Details

#initialize(subject: nil, graph: nil, values: nil, wrap_transaction: false) {|list| ... } ⇒ List

Initializes a newly-constructed list.

Instantiates a new list based at ‘subject`, which should be an RDF::Node. List may be initialized using passed `values`.

If a ‘values` initializer is set with an empty list, `subject` will be used as the first element in the list. Otherwise, if the list is not empty, `subject` identifies the first element of the list to which `values` are prepended yielding a new `subject`. Otherwise, if there are no initial `values`, and `subject` does not identify an existing list in `graph`, the list remains identified by `subject`, but will be invalid.

Examples:

add constructed list to existing graph

l = RDF::List(values: (1, 2, 3))
g = RDF::Graph.new << l
g.count # => l.count

use a transaction for block initialization

l = RDF::List(graph: graph, wrap_transaction: true) do |list|
  list << RDF::Literal(1)
  # list.graph.rollback will rollback all list changes within this block.
end
list.count #=> 1

Parameters:

  • subject (RDF::Resource) (defaults to: nil)

    (RDF.nil) Subject should be an Node, not a URI. A list with an IRI head will not validate, but is commonly used to detect if a list is valid.

  • graph (RDF::Graph) (defaults to: nil)

    (RDF::Graph.new)

  • values (Array<RDF::Term>) (defaults to: nil)

    Any values which are not terms are coerced to ‘RDF::Literal`.

  • wrap_transaction (Boolean) (defaults to: false)

    (false) Wraps the callback in a transaction, and replaces the graph with that transaction for the duraction of the callback. This has the effect of allowing any list changes to be made atomically, or rolled back.

Yields:

  • (list)

Yield Parameters:

Since:

  • 0.2.3



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rdf/model/list.rb', line 68

def initialize(subject: nil, graph: nil, values: nil, wrap_transaction: false, &block)
  @subject = subject || RDF.nil
  @graph   = graph   || RDF::Graph.new
  is_empty = @graph.query({subject: subject, predicate: RDF.first}).empty?

  if subject && is_empty
    # An empty list with explicit subject and value initializers
    @subject = RDF.nil
    first, *values = Array(values)
    if first || values.length > 0
      # Intantiate the list from values, and insert the first value using subject.
      values.reverse_each {|value| self.unshift(value)}
      @graph.insert RDF::Statement(subject, RDF.first, first || RDF.nil)
      @graph.insert RDF::Statement(subject, RDF.rest, @subject)
    end
    @subject = subject
  else
    # Otherwise, prepend any values, which resets @subject
    Array(values).reverse_each {|value| self.unshift(value)}
  end

  if block_given?
    if wrap_transaction
      old_graph = @graph
      begin
        Transaction.begin(@graph, graph_name: @graph.graph_name, mutable: @graph.mutable?) do |trans|
          @graph = trans
          case block.arity
            when 1 then block.call(self)
            else instance_eval(&block)
          end
          trans.execute if trans.mutated?
        end
      ensure
        @graph = old_graph
      end
    else
      case block.arity
        when 1 then block.call(self)
        else instance_eval(&block)
      end
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Enumerable

Instance Attribute Details

#graphRDF::Graph (readonly)

Returns the underlying graph storing the statements that constitute this list.

Returns:

  • (RDF::Graph)

    the underlying graph storing the statements that constitute this list

Since:

  • 0.2.3



179
180
181
# File 'lib/rdf/model/list.rb', line 179

def graph
  @graph
end

#subjectRDF::Resource (readonly)

Returns the subject term of this list.

Returns:

Since:

  • 0.2.3



175
176
177
# File 'lib/rdf/model/list.rb', line 175

def subject
  @subject
end

Class Method Details

.[](*values) ⇒ RDF::List

Constructs a new list from the given ‘values`.

The list will be identified by a new autogenerated blank node, and backed by an initially empty in-memory graph.

Examples:

RDF::List[]
RDF::List[*(1..10)]
RDF::List[1, 2, 3]
RDF::List["foo", "bar"]
RDF::List["a", 1, "b", 2, "c", 3]

Parameters:

Returns:

Since:

  • 0.2.3



30
31
32
# File 'lib/rdf/model/list.rb', line 30

def self.[](*values)
  self.new(subject: nil, graph: nil, values: values)
end

Instance Method Details

#&(other) ⇒ RDF::List

Returns the set intersection of this list and ‘other`.

The resulting list contains the elements common to both lists, with no duplicates.

Examples:

RDF::List[1, 2] & RDF::List[1, 2]       #=> RDF::List[1, 2]
RDF::List[1, 2] & RDF::List[2, 3]       #=> RDF::List[2]
RDF::List[1, 2] & RDF::List[3, 4]       #=> RDF::List[]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



202
203
204
# File 'lib/rdf/model/list.rb', line 202

def &(other)
  self.class.new(values: (to_a & other.to_a))
end

#*(times) ⇒ RDF::List #*(sep) ⇒ RDF::List

Returns either a repeated list or a string concatenation of the elements in this list.

Overloads:

  • #*(times) ⇒ RDF::List

    Returns a new list built of ‘times` repetitions of this list.

    Examples:

    RDF::List[1, 2, 3] * 2                #=> RDF::List[1, 2, 3, 1, 2, 3]

    Parameters:

    • times (Integer)

    Returns:

  • #*(sep) ⇒ RDF::List

    Returns the string concatenation of the elements in this list separated by ‘sep`. Equivalent to `self.join(sep)`.

    Examples:

    RDF::List[1, 2, 3] * ","              #=> "1,2,3"

    Parameters:

    • sep (String, #to_s)

    Returns:

Returns:

See Also:

Since:

  • 0.2.3



276
277
278
279
280
281
# File 'lib/rdf/model/list.rb', line 276

def *(int_or_str)
  case int_or_str
    when Integer then self.class.new(values: (to_a * int_or_str))
    else join(int_or_str.to_s)
  end
end

#+(other) ⇒ RDF::List

Returns the concatenation of this list and ‘other`.

Examples:

RDF::List[1, 2] + RDF::List[3, 4]       #=> RDF::List[1, 2, 3, 4]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



233
234
235
# File 'lib/rdf/model/list.rb', line 233

def +(other)
  self.class.new(values: (to_a + other.to_a))
end

#-(other) ⇒ RDF::List

Returns the difference between this list and ‘other`, removing any elements that appear in both lists.

Examples:

RDF::List[1, 2, 2, 3] - RDF::List[2]    #=> RDF::List[1, 3]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



247
248
249
# File 'lib/rdf/model/list.rb', line 247

def -(other)
  self.class.new(values: (to_a - other.to_a))
end

#<<(value) ⇒ RDF::List

Appends an element to the tail of this list.

Examples:

RDF::List[] << 1 << 2 << 3              #=> RDF::List[1, 2, 3]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/rdf/model/list.rb', line 438

def <<(value)
  value = normalize_value(value)

  if empty?
    @subject = new_subject = RDF::Node.new
  else
    old_subject, new_subject = last_subject, RDF::Node.new
    graph.delete([old_subject, RDF.rest, RDF.nil])
    graph.insert([old_subject, RDF.rest, new_subject])
  end

  graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
  graph.insert([new_subject, RDF.rest, RDF.nil])

  self
end

#<=>(other) ⇒ Integer

Compares this list to ‘other` for sorting purposes.

Examples:

RDF::List[1] <=> RDF::List[1]           #=> 0
RDF::List[1] <=> RDF::List[2]           #=> -1
RDF::List[2] <=> RDF::List[1]           #=> 1

Parameters:

Returns:

  • (Integer)

See Also:

Since:

  • 0.2.3



480
481
482
# File 'lib/rdf/model/list.rb', line 480

def <=>(other)
  to_a <=> Array(other)
end

#==(other) ⇒ Object

See Also:

  • Value#==

Since:

  • 0.2.3



183
184
185
186
# File 'lib/rdf/model/list.rb', line 183

def ==(other)
  return false if other.is_a?(RDF::Value) && !other.list?
  super
end

#[]=(index, term) ⇒ RDF::Term #[]=(start, length, value) ⇒ RDF::Term, RDF::List #[]=(range, value) ⇒ RDF::Term, RDF::List

Element Assignment — Sets the element at ‘index`, or replaces a subarray from the `start` index for `length` elements, or replaces a subarray specified by the `range` of indices.

If indices are greater than the current capacity of the array, the array grows automatically. Elements are inserted into the array at ‘start` if length is zero.

Negative indices will count backward from the end of the array. For ‘start` and `range` cases the starting index is just before an element.

An ‘IndexError` is raised if a negative index points past the beginning of the array.

(see #unshift).

Examples:

a = RDF::List.new
a[4] = "4";                 #=> [rdf:nil, rdf:nil, rdf:nil, rdf:nil, "4"]
a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", rdf:nil, "4"]
a[1..2] = [ 1, 2 ]          #=> ["a", 1, 2, rdf:nil, "4"]
a[0, 2] = "?"               #=> ["?", 2, rdf:nil, "4"]
a[0..2] = "A"               #=> ["A", "4"]
a[-1]   = "Z"               #=> ["A", "Z"]
a[1..-1] = nil              #=> ["A", rdf:nil]
a[1..-1] = []               #=> ["A"]
a[0, 0] = [ 1, 2 ]          #=> [1, 2, "A"]
a[3, 0] = "B"               #=> [1, 2, "A", "B"]

Overloads:

Since:

  • 1.1.15



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/rdf/model/list.rb', line 332

def []=(*args)
  start, length = 0, 0

  ary = self.to_a

  value = case args.last
  when Array then args.last
  when RDF::List then args.last.to_a
  else [args.last]
  end

  ret = case args.length
  when 3
    start, length = args[0], args[1]
    ary[start, length] = value
  when 2
    case args.first
    when Integer
      raise ArgumentError, "Index form of []= takes a single term" if args.last.is_a?(Array)
      ary[args.first] = args.last.is_a?(RDF::List) ? args.last.subject : args.last
    when Range
      ary[args.first] = value
    else
      raise ArgumentError, "Index form of must use an integer or range"
    end
  else
    raise ArgumentError, "List []= takes one or two index values"
  end

  # Clear the list and create a new list using the existing subject
  subject = @subject unless ary.empty? || @subject == RDF.nil
  self.clear
  new_list = RDF::List.new(subject: subject, graph: @graph, values: ary)
  @subject = new_list.subject
  ret # Returns inserted values
end

#at(index) ⇒ RDF::Term? Also known as: nth

Returns the element at ‘index`.

Examples:

RDF::List[1, 2, 3].at(0)                #=> 1
RDF::List[1, 2, 3].at(4)                #=> nil

Returns:

See Also:

Since:

  • 0.2.3



596
597
598
599
# File 'lib/rdf/model/list.rb', line 596

def at(index)
  each.with_index { |v, i| return v if i == index }
  return nil
end

#clearRDF::List

Empties this list

Examples:

RDF::List[1, 2, 2, 3].clear    #=> RDF::List[]

Returns:

See Also:

Since:

  • 0.2.3



422
423
424
425
426
427
# File 'lib/rdf/model/list.rb', line 422

def clear
  until empty?
    shift
  end
  return self
end

#eachEnumerator

Yields each element in this list.

Examples:

RDF::List[1, 2, 3].each do |value|
  puts value.inspect
end

Returns:

See Also:

Since:

  • 0.2.3



813
814
815
816
817
818
819
820
821
# File 'lib/rdf/model/list.rb', line 813

def each
  return to_enum unless block_given?

  each_subject do |subject|
    if value = graph.first_object(subject: subject, predicate: RDF.first)
      yield value # FIXME
    end
  end
end

#each_statement(&block) ⇒ Enumerator Also known as: to_rdf

Yields each statement constituting this list.

Examples:

RDF::List[1, 2, 3].each_statement do |statement|
  puts statement.inspect
end

Returns:

See Also:

Since:

  • 0.2.3



833
834
835
836
837
838
839
# File 'lib/rdf/model/list.rb', line 833

def each_statement(&block)
  return enum_statement unless block_given?

  each_subject do |subject|
    graph.query({subject: subject}, &block)
  end
end

#each_subject {|subject| ... } ⇒ Enumerator

Yields each subject term constituting this list.

Examples:

RDF::List[1, 2, 3].each_subject do |subject|
  puts subject.inspect
end

Yields:

Returns:

See Also:

  • Enumerable#each

Since:

  • 0.2.3



790
791
792
793
794
795
796
797
798
799
800
801
# File 'lib/rdf/model/list.rb', line 790

def each_subject
  return enum_subject unless block_given?

  subject = self.subject
  yield subject

  loop do
    rest = graph.first_object(subject: subject, predicate: RDF.rest)
    break if rest.nil? || rest.eql?(RDF.nil)
    yield subject = rest
  end
end

#eighthRDF::Term

Returns the eighth element in this list.

Examples:

RDF::List[*(1..10)].eighth              #=> RDF::Literal(8)

Returns:

Since:

  • 0.2.3



687
688
689
# File 'lib/rdf/model/list.rb', line 687

def eighth
  at(7)
end

#empty?Boolean

Returns ‘true` if this list is empty.

Examples:

RDF::List[].empty?                      #=> true
RDF::List[1, 2, 3].empty?               #=> false

Returns:

  • (Boolean)

See Also:

Since:

  • 0.2.3



493
494
495
# File 'lib/rdf/model/list.rb', line 493

def empty?
  graph.query({subject: subject, predicate: RDF.first}).empty?
end

#eql?(other) ⇒ Integer

Compares this list to ‘other` using eql? on each component.

Examples:

RDF::List[1, 2, 3].eql? RDF::List[1, 2, 3]  #=> true
RDF::List[1, 2, 3].eql? [1, 2, 3]           #=> true

Parameters:

Returns:

  • (Integer)

See Also:

Since:

  • 0.2.3



465
466
467
# File 'lib/rdf/model/list.rb', line 465

def eql?(other)
  to_a.eql? Array(other)
end

#fetch(index, default = UNSET) ⇒ RDF::Term?

Returns element at ‘index` with default.

Examples:

RDF::List[1, 2, 3].fetch(0)             #=> RDF::Literal(1)
RDF::List[1, 2, 3].fetch(4)             #=> IndexError
RDF::List[1, 2, 3].fetch(4, nil)        #=> nil
RDF::List[1, 2, 3].fetch(4) { |n| n*n } #=> 16

Returns:

See Also:

Since:

  • 0.2.3



576
577
578
579
580
581
582
583
584
585
# File 'lib/rdf/model/list.rb', line 576

def fetch(index, default = UNSET)
  val = at(index)
  return val unless val.nil?

  case
    when block_given?         then yield index
    when !default.eql?(UNSET) then default
    else raise IndexError, "index #{index} not in the list #{self.inspect}"
  end
end

#fifthRDF::Term

Returns the fifth element in this list.

Examples:

RDF::List[*(1..10)].fifth               #=> RDF::Literal(5)

Returns:

Since:

  • 0.2.3



654
655
656
# File 'lib/rdf/model/list.rb', line 654

def fifth
  at(4)
end

#firstRDF::Term

Returns the first element in this list.

Examples:

RDF::List[*(1..10)].first               #=> RDF::Literal(1)

Returns:

Since:

  • 0.2.3



610
611
612
# File 'lib/rdf/model/list.rb', line 610

def first
  graph.first_object(subject: first_subject, predicate: RDF.first)
end

#first_subjectRDF::Resource

Returns the first subject term constituting this list.

This is equivalent to ‘subject`.

Examples:

RDF::List[1, 2, 3].first_subject        #=> RDF::Node(...)

Returns:

Since:

  • 0.2.3



756
757
758
# File 'lib/rdf/model/list.rb', line 756

def first_subject
  subject
end

#fourthRDF::Term

Returns the fourth element in this list.

Examples:

RDF::List[*(1..10)].fourth              #=> RDF::Literal(4)

Returns:

Since:

  • 0.2.3



643
644
645
# File 'lib/rdf/model/list.rb', line 643

def fourth
  at(3)
end

#index(value) ⇒ Integer

Returns the index of the first element equal to ‘value`, or `nil` if no match was found.

Examples:

RDF::List['a', 'b', 'c'].index('a')     #=> 0
RDF::List['a', 'b', 'c'].index('d')     #=> nil

Parameters:

Returns:

  • (Integer)

See Also:

Since:

  • 0.2.3



523
524
525
526
527
528
# File 'lib/rdf/model/list.rb', line 523

def index(value)
  each.with_index do |v, i|
    return i if v == value
  end
  return nil
end

#inspectString

Returns a developer-friendly representation of this list.

Examples:

RDF::List[].inspect                     #=> "#<RDF::List(_:g2163790380)>"

Returns:

  • (String)

Since:

  • 0.2.3



960
961
962
963
964
965
966
# File 'lib/rdf/model/list.rb', line 960

def inspect
  if self.equal?(NIL)
    'RDF::List::NIL'
  else
    sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, join(', '))
  end
end

#join(sep = $,) ⇒ String

Returns a string created by converting each element of this list into a string, separated by ‘sep`.

Examples:

RDF::List[1, 2, 3].join                 #=> "123"
RDF::List[1, 2, 3].join(", ")           #=> "1, 2, 3"

Parameters:

  • sep (String) (defaults to: $,)

Returns:

  • (String)

See Also:

Since:

  • 0.2.3



853
854
855
# File 'lib/rdf/model/list.rb', line 853

def join(sep = $,)
  map(&:to_s).join(sep)
end

#lastRDF::Term

Returns the last element in this list.

Examples:

RDF::List[*(1..10)].last                 #=> RDF::Literal(10)

Returns:

See Also:

Since:

  • 0.2.3



721
722
723
# File 'lib/rdf/model/list.rb', line 721

def last
  graph.first_object(subject: last_subject, predicate: RDF.first)
end

#last_subjectRDF::Resource

Returns the last subject term constituting this list.

Examples:

RDF::List[1, 2, 3].last_subject         #=> RDF::Node(...)

Returns:

Since:

  • 0.2.3



776
777
778
# File 'lib/rdf/model/list.rb', line 776

def last_subject
  each_subject.to_a.last # TODO: optimize this
end

#lengthInteger Also known as: size

Returns the length of this list.

Examples:

RDF::List[].length                      #=> 0
RDF::List[1, 2, 3].length               #=> 3

Returns:

  • (Integer)

See Also:

Since:

  • 0.2.3



506
507
508
# File 'lib/rdf/model/list.rb', line 506

def length
  each.count
end

#list?Boolean

Is this a RDF::List?

Returns:

  • (Boolean)

Since:

  • 0.2.3



122
123
124
# File 'lib/rdf/model/list.rb', line 122

def list?
  true
end

#ninthRDF::Term

Returns the ninth element in this list.

Examples:

RDF::List[*(1..10)].ninth               #=> RDF::Literal(9)

Returns:

Since:

  • 0.2.3



698
699
700
# File 'lib/rdf/model/list.rb', line 698

def ninth
  at(8)
end

#restRDF::List

Returns a list containing all but the first element of this list.

Examples:

RDF::List[1, 2, 3].rest                 #=> RDF::List[2, 3]

Returns:

Since:

  • 0.2.3



732
733
734
# File 'lib/rdf/model/list.rb', line 732

def rest
  (subject = rest_subject).eql?(RDF.nil) ? nil : self.class.new(subject: subject, graph: graph)
end

#rest_subjectRDF::Resource

Examples:

RDF::List[1, 2, 3].rest_subject         #=> RDF::Node(...)

Returns:

Since:

  • 0.2.3



765
766
767
# File 'lib/rdf/model/list.rb', line 765

def rest_subject
  graph.first_object(subject: subject, predicate: RDF.rest)
end

#reverseRDF::List

Returns the elements in this list in reversed order.

Examples:

RDF::List[1, 2, 3].reverse              #=> RDF::List[3, 2, 1]

Returns:

See Also:

Since:

  • 0.2.3



865
866
867
# File 'lib/rdf/model/list.rb', line 865

def reverse
  self.class.new(values: to_a.reverse)
end

#secondRDF::Term

Returns the second element in this list.

Examples:

RDF::List[*(1..10)].second              #=> RDF::Literal(2)

Returns:

Since:

  • 0.2.3



621
622
623
# File 'lib/rdf/model/list.rb', line 621

def second
  at(1)
end

#seventhRDF::Term

Returns the seventh element in this list.

Examples:

RDF::List[*(1..10)].seventh             #=> RDF::Literal(7)

Returns:

Since:

  • 0.2.3



676
677
678
# File 'lib/rdf/model/list.rb', line 676

def seventh
  at(6)
end

#shiftRDF::Term

Removes and returns the element at the head of this list.

Examples:

RDF::List[1,2,3].shift              #=> 1

Returns:

See Also:

Since:

  • 0.2.3



401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/rdf/model/list.rb', line 401

def shift
  return nil if empty?

  value = first
  old_subject, new_subject = subject, rest_subject
  graph.delete([old_subject, RDF.type, RDF.List])
  graph.delete([old_subject, RDF.first, value])
  graph.delete([old_subject, RDF.rest, new_subject])

  @subject = new_subject
  return value
end

#sixthRDF::Term

Returns the sixth element in this list.

Examples:

RDF::List[*(1..10)].sixth               #=> RDF::Literal(6)

Returns:

Since:

  • 0.2.3



665
666
667
# File 'lib/rdf/model/list.rb', line 665

def sixth
  at(5)
end

#slice(*args) ⇒ RDF::Term Also known as: []

Returns a slice of a list.

Examples:

RDF::List[1, 2, 3].slice(0)    #=> RDF::Literal(1),
RDF::List[1, 2, 3].slice(0, 2) #=> RDF::List[1, 2],
RDF::List[1, 2, 3].slice(0..2) #=> RDF::List[1, 2, 3]

Returns:

See Also:

Since:

  • 0.2.3



540
541
542
543
544
545
546
547
# File 'lib/rdf/model/list.rb', line 540

def slice(*args)
  case argc = args.size
    when 2 then slice_with_start_and_length(*args)
    when 1 then (arg = args.first).is_a?(Range) ? slice_with_range(arg) : at(arg)
    when 0 then raise ArgumentError, "wrong number of arguments (0 for 1)"
    else raise ArgumentError, "wrong number of arguments (#{argc} for 2)"
  end
end

#sort(&block) ⇒ RDF::List

Returns the elements in this list in sorted order.

Examples:

RDF::List[2, 3, 1].sort                 #=> RDF::List[1, 2, 3]

Returns:

See Also:

Since:

  • 0.2.3



877
878
879
# File 'lib/rdf/model/list.rb', line 877

def sort(&block)
  self.class.new(values: super)
end

#sort_by(&block) ⇒ RDF::List

Returns the elements in this list in sorted order.

Examples:

RDF::List[2, 3, 1].sort_by(&:to_i)      #=> RDF::List[1, 2, 3]

Returns:

See Also:

Since:

  • 0.2.3



889
890
891
# File 'lib/rdf/model/list.rb', line 889

def sort_by(&block)
  self.class.new(values: super)
end

#tailRDF::List

Returns a list containing the last element of this list.

Examples:

RDF::List[1, 2, 3].tail                 #=> RDF::List[3]

Returns:

Since:

  • 0.2.3



743
744
745
# File 'lib/rdf/model/list.rb', line 743

def tail
  (subject = last_subject).eql?(RDF.nil) ? nil : self.class.new(subject: subject, graph: graph)
end

#tenthRDF::Term

Returns the tenth element in this list.

Examples:

RDF::List[*(1..10)].tenth               #=> RDF::Literal(10)

Returns:

Since:

  • 0.2.3



709
710
711
# File 'lib/rdf/model/list.rb', line 709

def tenth
  at(9)
end

#thirdRDF::Term

Returns the third element in this list.

Examples:

RDF::List[*(1..10)].third               #=> RDF::Literal(4)

Returns:

Since:

  • 0.2.3



632
633
634
# File 'lib/rdf/model/list.rb', line 632

def third
  at(2)
end

#to_aArray

Returns the elements in this list as an array.

Examples:

RDF::List[].to_a                        #=> []
RDF::List[1, 2, 3].to_a                 #=> [RDF::Literal(1), RDF::Literal(2), RDF::Literal(3)]

Returns:

  • (Array)

Since:

  • 0.2.3



913
914
915
# File 'lib/rdf/model/list.rb', line 913

def to_a
  each.to_a
end

#to_sString

Returns a string representation of this list.

Examples:

RDF::List[].to_s                        #=> "RDF::List[]"
RDF::List[1, 2, 3].to_s                 #=> "RDF::List[1, 2, 3]"

Returns:

  • (String)

Since:

  • 0.2.3



949
950
951
# File 'lib/rdf/model/list.rb', line 949

def to_s
  'RDF::List[' + join(', ') + ']'
end

#to_setSet

Returns the elements in this list as a set.

Examples:

RDF::List[1, 2, 3].to_set               #=> Set[RDF::Literal(1), RDF::Literal(2), RDF::Literal(3)]

Returns:

  • (Set)

Since:

  • 0.2.3



924
925
926
927
# File 'lib/rdf/model/list.rb', line 924

def to_set
  require 'set' unless defined?(::Set)
  each.to_set
end

#to_termRDF::Resource

Returns the subject of the list.

Examples:

RDF::List[].to_term                     #=> "RDF[:nil]"
RDF::List[1, 2, 3].to_term              #=> "RDF::Node"

Returns:

Since:

  • 0.2.3



937
938
939
# File 'lib/rdf/model/list.rb', line 937

def to_term
  subject
end

#uniqRDF::List

Returns a new list with the duplicates in this list removed.

Examples:

RDF::List[1, 2, 2, 3].uniq              #=> RDF::List[1, 2, 3]

Returns:

See Also:

Since:

  • 0.2.3



901
902
903
# File 'lib/rdf/model/list.rb', line 901

def uniq
  self.class.new(values: to_a.uniq)
end

#unshift(value) ⇒ RDF::List

Appends an element to the head of this list. Existing references are not updated, as the list subject changes as a side-effect.

Examples:

RDF::List[].unshift(1).unshift(2).unshift(3) #=> RDF::List[3, 2, 1]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/rdf/model/list.rb', line 380

def unshift(value)
  value = normalize_value(value)

  new_subject, old_subject = RDF::Node.new, subject

  graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
  graph.insert([new_subject, RDF.rest, old_subject])

  @subject = new_subject

  return self
end

#valid?Boolean

Validate the list ensuring that

  • each node is referenced exactly once (except for the head, which may have no reference)

  • rdf:rest values are all BNodes are nil

  • each subject has exactly one value for ‘rdf:first` and `rdf:rest`.

  • The value of ‘rdf:rest` must be either a BNode or `rdf:nil`.

  • only the list head may have any other properties

Returns:

  • (Boolean)

Since:

  • 0.2.3



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rdf/model/list.rb', line 135

def valid?
  li = subject
  list_nodes = []
  while li != RDF.nil do
    return false if list_nodes.include?(li)
    list_nodes << li
    rest = nil
    firsts = rests = 0
    @graph.query({subject: li}) do |st|
      return false unless st.subject.node?
      case st.predicate
      when RDF.first
        firsts += 1
      when RDF.rest
        rest = st.object
        return false unless rest.node? || rest == RDF.nil
        rests += 1
      when RDF.type
      else
        # It may have no other properties
        return false unless li == subject
      end
    end
    return false unless firsts == 1 && rests == 1
    li = rest
  end

  # All elements other than the head must be referenced exactly once
  return list_nodes.all? do |li|
    refs = @graph.query({object: li}).count
    case refs
    when 0 then li == subject
    when 1 then true
    else        false
    end
  end
end

#|(other) ⇒ RDF::List

Returns the set union of this list and ‘other`.

The resulting list contains the elements from both lists, with no duplicates.

Examples:

RDF::List[1, 2] | RDF::List[1, 2]       #=> RDF::List[1, 2]
RDF::List[1, 2] | RDF::List[2, 3]       #=> RDF::List[1, 2, 3]
RDF::List[1, 2] | RDF::List[3, 4]       #=> RDF::List[1, 2, 3, 4]

Parameters:

Returns:

See Also:

Since:

  • 0.2.3



220
221
222
# File 'lib/rdf/model/list.rb', line 220

def |(other)
  self.class.new(values: (to_a | other.to_a))
end