class RDF::RDF::RDF::List

An RDF list.

@example Constructing a new list

RDF::List[1, 2, 3]

@since 0.2.3

Constants

NIL

The canonical empty list.

UNSET

Attributes

graph[R]

@!attribute [r] graph @return [RDF::Graph] the underlying graph storing the statements that constitute this list

subject[R]

@!attribute [r] subject @return [RDF::Resource] the subject term of this list.

Public Class Methods

[](*values) click to toggle source

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.

@example

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

@param [Array<RDF::Term>] values @return [RDF::List]

# File lib/rdf/model/list.rb, line 29
def self.[](*values)
  self.new(subject: nil, graph: nil, values: values)
end
new(subject: nil, graph: nil, values: nil, &block) click to toggle source

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.

@example add constructed list to existing graph

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

@param [RDF::Resource] subject (RDF.nil)

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

@param [RDF::Graph] graph (RDF::Graph.new) @param [Array<RDF::Term>] values

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

@yield [list] @yieldparam [RDF::List] list

# File lib/rdf/model/list.rb, line 58
def initialize(subject: nil, graph: nil, values: nil, &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?
    case block.arity
      when 1 then block.call(self)
      else instance_eval(&block)
    end
  end
end

Public Instance Methods

&(other) click to toggle source

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

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

@example

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[]

@param [RDF::List] other @return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-26

# File lib/rdf/model/list.rb, line 162
def &(other)
  RDF::List[*(to_a & other.to_a)]
end
*(int_or_str) click to toggle source

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

@overload *(times)

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

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

@param  [Integer] times
@return [RDF::List]

@overload *(sep)

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

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

@param  [String, #to_s] sep
@return [RDF::List]

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-2A

# File lib/rdf/model/list.rb, line 236
def *(int_or_str)
  case int_or_str
    when Integer then RDF::List[*(to_a * int_or_str)]
    else join(int_or_str.to_s)
  end
end
+(other) click to toggle source

Returns the concatenation of this list and `other`.

@example

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

@param [RDF::List] other @return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-2B

# File lib/rdf/model/list.rb, line 193
def +(other)
  RDF::List[*(to_a + other.to_a)]
end
-(other) click to toggle source

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

@example

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

@param [RDF::List] other @return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-2D

# File lib/rdf/model/list.rb, line 207
def -(other)
  RDF::List[*(to_a - other.to_a)]
end
<<(value) click to toggle source

Appends an element to the tail of this list.

@example

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

@param [RDF::Term] value @return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-3C-3C

# File lib/rdf/model/list.rb, line 411
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) click to toggle source

Compares this list to `other` for sorting purposes.

@example

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

@param [RDF::List] other @return [Integer] @see ruby-doc.org/core-2.2.2/Array.html#method-i-3C-3D-3E

# File lib/rdf/model/list.rb, line 453
def <=>(other)
  to_a <=> Array(other)
end
==(other) click to toggle source

@see RDF::Value#==

Calls superclass method
# File lib/rdf/model/list.rb, line 143
def ==(other)
  return false if other.is_a?(RDF::Value) && !other.list?
  super
end
[](index) click to toggle source

Returns the element at `index`.

@example

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

@param [Integer] index @return [RDF::Term] @see ruby-doc.org/core-2.2.2/Array.html#method-i-5B-5D

# File lib/rdf/model/list.rb, line 252
def [](index)
  at(index)
end
[]=(*args) click to toggle source

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

@example

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"]

@overload []=(index, term)

Replaces the element at `index` with `term`.
@param [Integer] index
@param [RDF::Term] term
  A non-RDF::Term is coerced to a Literal.
@return [RDF::Term]
@raise [IndexError]

@overload []=(start, length, value)

Replaces a subarray from the `start` index for `length` elements with `value`. Value is a {RDF::Term}, Array of {RDF::Term}, or {RDF::List}.
@param [Integer] start
@param [Integer] length
@param [RDF::Term, Array<RDF::Term>, RDF::List] value
  A non-RDF::Term is coerced to a Literal.
@return [RDF::Term, RDF::List]
@raise [IndexError]

@overload []=(range, value)

Replaces a subarray from the `start` index for `length` elements with `value`. Value is a {RDF::Term}, Array of {RDF::Term}, or {RDF::List}.
@param [Range] range
@param [RDF::Term, Array<RDF::Term>, RDF::List] value
  A non-RDF::Term is coerced to a Literal.
@return [RDF::Term, RDF::List]
@raise [IndexError]

@since 1.1.15

# File lib/rdf/model/list.rb, line 305
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) click to toggle source

Returns the element at `index`.

@example

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

@return [RDF::Term, nil] @see ruby-doc.org/core-2.2.2/Array.html#method-i-at

# File lib/rdf/model/list.rb, line 569
def at(index)
  each.with_index { |v, i| return v if i == index }
  return nil
end
Also aliased as: nth
clear() click to toggle source

Empties this list

@example

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

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-clear

# File lib/rdf/model/list.rb, line 395
def clear
  until empty?
    shift
  end
  return self
end
each() { |value| ... } click to toggle source

Yields each element in this list.

@example

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

@return [Enumerator] @see ruby-doc.org/core-1.9/classes/Enumerable.html

# File lib/rdf/model/list.rb, line 786
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) click to toggle source

Yields each statement constituting this list.

@example

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

@return [Enumerator] @see RDF::Enumerable#each_statement

# File lib/rdf/model/list.rb, line 806
def each_statement(&block)
  return enum_statement unless block_given?

  each_subject do |subject|
    graph.query(subject: subject, &block)
  end
end
Also aliased as: to_rdf
each_subject() { |subject| ... } click to toggle source

Yields each subject term constituting this list.

@example

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

@return [Enumerator] @see RDF::Enumerable#each

# File lib/rdf/model/list.rb, line 763
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
eighth() click to toggle source

Returns the eighth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 660
def eighth
  at(7)
end
empty?() click to toggle source

Returns `true` if this list is empty.

@example

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

@return [Boolean] @see ruby-doc.org/core-2.2.2/Array.html#method-i-empty-3F

# File lib/rdf/model/list.rb, line 466
def empty?
  graph.query(subject: subject, predicate: RDF.first).empty?
end
eql?(other) click to toggle source

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

@example

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

@param [RDF::List] other @return [Integer] @see ruby-doc.org/core-2.2.2/Array.html#method-i-3C-3D-3E

# File lib/rdf/model/list.rb, line 438
def eql?(other)
  to_a.eql? other.to_a # TODO: optimize this
end
fetch(index, default = UNSET) { |index| ... } click to toggle source

Returns element at `index` with default.

@example

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

@return [RDF::Term, nil] @see ruby-doc.org/core-1.9/classes/Array.html#M000420

# File lib/rdf/model/list.rb, line 549
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
fifth() click to toggle source

Returns the fifth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 627
def fifth
  at(4)
end
first() click to toggle source

Returns the first element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 583
def first
  graph.first_object(subject: first_subject, predicate: RDF.first)
end
first_subject() click to toggle source

Returns the first subject term constituting this list.

This is equivalent to `subject`.

@example

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

@return [RDF::Resource]

# File lib/rdf/model/list.rb, line 729
def first_subject
  subject
end
fourth() click to toggle source

Returns the fourth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 616
def fourth
  at(3)
end
index(value) click to toggle source

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

@example

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

@param [RDF::Term] value @return [Integer] @see ruby-doc.org/core-2.2.2/Array.html#method-i-index

# File lib/rdf/model/list.rb, line 496
def index(value)
  each.with_index do |v, i|
    return i if v == value
  end
  return nil
end
inspect() click to toggle source

Returns a developer-friendly representation of this list.

@example

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

@return [String]

# File lib/rdf/model/list.rb, line 933
def inspect
  if self.equal?(NIL)
    'RDF::List::NIL'
  else
    sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, join(', '))
  end
end
join(sep = $,) click to toggle source

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

@example

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

@param [String] sep @return [String] @see ruby-doc.org/core-2.2.2/Array.html#method-i-join

# File lib/rdf/model/list.rb, line 826
def join(sep = $,)
  map(&:to_s).join(sep)
end
last() click to toggle source

Returns the last element in this list.

@example

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

@return [RDF::Term] @see ruby-doc.org/core-2.2.2/Array.html#method-i-last

# File lib/rdf/model/list.rb, line 694
def last
  graph.first_object(subject: last_subject, predicate: RDF.first)
end
last_subject() click to toggle source

Returns the last subject term constituting this list.

@example

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

@return [RDF::Resource]

# File lib/rdf/model/list.rb, line 749
def last_subject
  each_subject.to_a.last # TODO: optimize this
end
length() click to toggle source

Returns the length of this list.

@example

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

@return [Integer] @see ruby-doc.org/core-2.2.2/Array.html#method-i-length

# File lib/rdf/model/list.rb, line 479
def length
  each.count
end
Also aliased as: size
list?() click to toggle source

Is this a {RDF::List}?

@return [Boolean]

# File lib/rdf/model/list.rb, line 96
def list?
  true
end
ninth() click to toggle source

Returns the ninth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 671
def ninth
  at(8)
end
nth(index)
Alias for: at
rest() click to toggle source

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

@example

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

@return [RDF::List]

# File lib/rdf/model/list.rb, line 705
def rest
  (subject = rest_subject).eql?(RDF.nil) ? nil : self.class.new(subject: subject, graph: graph)
end
rest_subject() click to toggle source

@example

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

@return [RDF::Resource]

# File lib/rdf/model/list.rb, line 738
def rest_subject
  graph.first_object(subject: subject, predicate: RDF.rest)
end
reverse() click to toggle source

Returns the elements in this list in reversed order.

@example

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

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-reverse

# File lib/rdf/model/list.rb, line 838
def reverse
  RDF::List[*to_a.reverse]
end
second() click to toggle source

Returns the second element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 594
def second
  at(1)
end
seventh() click to toggle source

Returns the seventh element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 649
def seventh
  at(6)
end
shift() click to toggle source

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

@example

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

@return [RDF::Term] @see ruby-doc.org/core-2.2.2/Array.html#method-i-shift

# File lib/rdf/model/list.rb, line 374
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
sixth() click to toggle source

Returns the sixth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 638
def sixth
  at(5)
end
size()
Alias for: length
slice(*args) click to toggle source

Returns a slice of a list.

@example

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]

@return [RDF::Term] @see ruby-doc.org/core-2.2.2/Array.html#method-i-slice

# File lib/rdf/model/list.rb, line 513
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
Also aliased as: []
sort(&block) click to toggle source

Returns the elements in this list in sorted order.

@example

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

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-sort

Calls superclass method
# File lib/rdf/model/list.rb, line 850
def sort(&block)
  RDF::List[*super]
end
sort_by(&block) click to toggle source

Returns the elements in this list in sorted order.

@example

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

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-sort_by

Calls superclass method
# File lib/rdf/model/list.rb, line 862
def sort_by(&block)
  RDF::List[*super]
end
tail() click to toggle source

Returns a list containing the last element of this list.

@example

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

@return [RDF::List]

# File lib/rdf/model/list.rb, line 716
def tail
  (subject = last_subject).eql?(RDF.nil) ? nil : self.class.new(subject: subject, graph: graph)
end
tenth() click to toggle source

Returns the tenth element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 682
def tenth
  at(9)
end
third() click to toggle source

Returns the third element in this list.

@example

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

@return [RDF::Term]

# File lib/rdf/model/list.rb, line 605
def third
  at(2)
end
to_a() click to toggle source

Returns the elements in this list as an array.

@example

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

@return [Array]

# File lib/rdf/model/list.rb, line 886
def to_a
  each.to_a
end
to_rdf(&block)
Alias for: each_statement
to_s() click to toggle source

Returns a string representation of this list.

@example

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

@return [String]

# File lib/rdf/model/list.rb, line 922
def to_s
  'RDF::List[' + join(', ') + ']'
end
to_set() click to toggle source

Returns the elements in this list as a set.

@example

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

@return [Set]

# File lib/rdf/model/list.rb, line 897
def to_set
  require 'set' unless defined?(::Set)
  each.to_set
end
to_term() click to toggle source

Returns the subject of the list.

@example

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

@return [RDF::Resource]

# File lib/rdf/model/list.rb, line 910
def to_term
  subject
end
uniq() click to toggle source

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

@example

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

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-uniq

# File lib/rdf/model/list.rb, line 874
def uniq
  RDF::List[*to_a.uniq]
end
unshift(value) click to toggle source

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

@example

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

@param [RDF::Term, Array<RDF::Term>, RDF::List] value

A non-RDF::Term is coerced to a Literal

@return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-unshift

# File lib/rdf/model/list.rb, line 353
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?() click to toggle source

Validate the list ensuring that

  • 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`.

  • All other properties are ignored.

@return [Boolean]

# File lib/rdf/model/list.rb, line 108
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
      end
    end
    return false unless firsts == 1 && rests == 1
    li = rest
  end
  true
end
|(other) click to toggle source

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

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

@example

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]

@param [RDF::List] other @return [RDF::List] @see ruby-doc.org/core-2.2.2/Array.html#method-i-7C

# File lib/rdf/model/list.rb, line 180
def |(other)
  RDF::List[*(to_a | other.to_a)]
end

Protected Instance Methods

slice_with_range(range) click to toggle source

@private

# File lib/rdf/model/list.rb, line 531
def slice_with_range(range)
  RDF::List[*to_a.slice(range)]
end
slice_with_start_and_length(start, length) click to toggle source

@private

# File lib/rdf/model/list.rb, line 525
def slice_with_start_and_length(start, length)
  RDF::List[*to_a.slice(start, length)]
end

Private Instance Methods

normalize_value(value) click to toggle source

Normalizes `Array` to `RDF::List` and `nil` to `RDF.nil`.

@param value [Object] @return [RDF::Value, Object] normalized value

# File lib/rdf/model/list.rb, line 948
def normalize_value(value)
  case value
    when nil         then RDF.nil
    when RDF::Value  then value
    when Array       then RDF::List.new(subject: nil, graph: graph, values: value)
    else value
  end
end