Class: RDF::List

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Resource
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(RDF.nil).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource

new, #resource?

Methods included from Term

#==, #constant?, #eql?, #variable?

Methods included from Value

#graph?, #inspect!, #iri?, #literal?, #node?, #resource?, #statement?, #to_ntriples, #to_quad, #to_rdf, #type_error, #uri?, #variable?

Methods included from Enumerable

#contexts, #dump, #each_context, #each_graph, #each_object, #each_predicate, #each_quad, #each_triple, #enum_context, #enum_graph, #enum_object, #enum_predicate, #enum_quad, #enum_statement, #enum_subject, #enum_triple, #has_context?, #has_object?, #has_predicate?, #has_quad?, #has_statement?, #has_subject?, #has_triple?, #objects, #predicates, #quads, #statements, #subjects, #supports?, #to_hash, #triples

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Countable

#count, #enum_for

Constructor Details

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

Initializes a newly-constructed list.

Parameters:

Yields:

  • (list)

Yield Parameters:

Since:

  • 0.2.3



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rdf/model/list.rb', line 40

def initialize(subject = nil, graph = nil, values = nil, &block)
  @subject = subject || RDF::Node.new
  @graph   = graph   || RDF::Graph.new

  values.each { |value| self << value } unless values.nil? || values.empty?

  if block_given?
    case block.arity
      when 1 then block.call(self)
      else instance_eval(&block)
    end
  end
end

Instance Attribute Details

#graphObject (readonly)

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

Since:

  • 0.2.3



103
104
105
# File 'lib/rdf/model/list.rb', line 103

def graph
  @graph
end

#subjectObject (readonly)

Returns the subject term of this list.

Since:

  • 0.2.3



96
97
98
# File 'lib/rdf/model/list.rb', line 96

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



28
29
30
# File 'lib/rdf/model/list.rb', line 28

def self.[](*values)
  self.new(nil, nil, 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



119
120
121
# File 'lib/rdf/model/list.rb', line 119

def &(other)
  RDF::List[*(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



193
194
195
196
197
198
# File 'lib/rdf/model/list.rb', line 193

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



150
151
152
# File 'lib/rdf/model/list.rb', line 150

def +(other)
  RDF::List[*(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



164
165
166
# File 'lib/rdf/model/list.rb', line 164

def -(other)
  RDF::List[*(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



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/rdf/model/list.rb', line 222

def <<(value)
  value = case value
    when nil         then RDF.nil
    when RDF::Value  then value
    when Array       then RDF::List.new(nil, graph, value)
    else value
  end

  if empty?
    new_subject = subject
  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.type, RDF.List])
  graph.insert([new_subject, RDF.first, 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



256
257
258
# File 'lib/rdf/model/list.rb', line 256

def <=>(other)
  to_a <=> other.to_a # TODO: optimize this
end

#[](index) ⇒ RDF::Term

Returns the element at ‘index`.

Examples:

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

Parameters:

  • index (Integer)

Returns:

See Also:

Since:

  • 0.2.3



209
210
211
# File 'lib/rdf/model/list.rb', line 209

def [](index)
  at(index)
end

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

Returns the element at ‘index`.

Examples:

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

Returns:

See Also:

Since:

  • 0.2.3



369
370
371
372
373
374
# File 'lib/rdf/model/list.rb', line 369

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

#each(&block) ⇒ Enumerator

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



588
589
590
591
592
593
594
595
596
# File 'lib/rdf/model/list.rb', line 588

def each(&block)
  return to_enum unless block_given?

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

#each_statement(&block) ⇒ Enumerator

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



608
609
610
611
612
613
614
# File 'lib/rdf/model/list.rb', line 608

def each_statement(&block)
  return enum_statement unless block_given?

  each_subject do |subject|
    graph.query(:subject => subject, &block)
  end
end

#each_subject(&block) ⇒ Enumerator

Yields each subject term constituting this list.

Examples:

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

Returns:

See Also:

  • Enumerable#each

Since:

  • 0.2.3



565
566
567
568
569
570
571
572
573
574
575
576
# File 'lib/rdf/model/list.rb', line 565

def each_subject(&block)
  return enum_subject unless block_given?

  subject = self.subject
  block.call(subject)

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

#eighthRDF::Term

Returns the eighth element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



462
463
464
# File 'lib/rdf/model/list.rb', line 462

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



269
270
271
# File 'lib/rdf/model/list.rb', line 269

def empty?
  graph.query(:subject => subject, :predicate => RDF.first).empty?
end

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

Returns the element at ‘index`.

Examples:

RDF::List[1, 2, 3].fetch(0)             #=> 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



349
350
351
352
353
354
355
356
357
358
359
# File 'lib/rdf/model/list.rb', line 349

def fetch(index, default = UNSET, &block)
  each.with_index do |v, i|
    return v if i == index
  end

  case
    when block_given?         then block.call(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               #=> 5

Returns:

Since:

  • 0.2.3



429
430
431
# File 'lib/rdf/model/list.rb', line 429

def fifth
  at(4)
end

#firstRDF::Term

Returns the first element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



385
386
387
# File 'lib/rdf/model/list.rb', line 385

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



531
532
533
# File 'lib/rdf/model/list.rb', line 531

def first_subject
  subject
end

#fourthRDF::Term

Returns the fourth element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



418
419
420
# File 'lib/rdf/model/list.rb', line 418

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



299
300
301
302
303
304
# File 'lib/rdf/model/list.rb', line 299

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



722
723
724
725
726
727
728
729
# File 'lib/rdf/model/list.rb', line 722

def inspect
  if self.equal?(NIL)
    'RDF::List::NIL'
  else
    #sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, subject.to_s)
    sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s) # FIXME
  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



627
628
629
# File 'lib/rdf/model/list.rb', line 627

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

#lastRDF::Term

Returns the last element in this list.

Examples:

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

Returns:

See Also:

Since:

  • 0.2.3



496
497
498
# File 'lib/rdf/model/list.rb', line 496

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



551
552
553
# File 'lib/rdf/model/list.rb', line 551

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



282
283
284
# File 'lib/rdf/model/list.rb', line 282

def length
  each.count
end

#ninthRDF::Term

Returns the ninth element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



473
474
475
# File 'lib/rdf/model/list.rb', line 473

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



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

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

#rest_subjectRDF::Resource

Examples:

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

Returns:

Since:

  • 0.2.3



540
541
542
# File 'lib/rdf/model/list.rb', line 540

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



639
640
641
# File 'lib/rdf/model/list.rb', line 639

def reverse
  RDF::List[*to_a.reverse]
end

#secondRDF::Term

Returns the second element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



396
397
398
# File 'lib/rdf/model/list.rb', line 396

def second
  at(1)
end

#seventhRDF::Term

Returns the seventh element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



451
452
453
# File 'lib/rdf/model/list.rb', line 451

def seventh
  at(6)
end

#sixthRDF::Term

Returns the sixth element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



440
441
442
# File 'lib/rdf/model/list.rb', line 440

def sixth
  at(5)
end

#slice(*args) ⇒ RDF::Term

Returns the element at ‘index`.

Examples:

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

Returns:

See Also:

Since:

  • 0.2.3



314
315
316
317
318
319
320
321
# File 'lib/rdf/model/list.rb', line 314

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



651
652
653
# File 'lib/rdf/model/list.rb', line 651

def sort(&block)
  RDF::List[*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



663
664
665
# File 'lib/rdf/model/list.rb', line 663

def sort_by(&block)
  RDF::List[*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



518
519
520
# File 'lib/rdf/model/list.rb', line 518

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

#tenthRDF::Term

Returns the tenth element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



484
485
486
# File 'lib/rdf/model/list.rb', line 484

def tenth
  at(9)
end

#thirdRDF::Term

Returns the third element in this list.

Examples:

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

Returns:

Since:

  • 0.2.3



407
408
409
# File 'lib/rdf/model/list.rb', line 407

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                 #=> [1, 2, 3]

Returns:

  • (Array)

Since:

  • 0.2.3



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

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



711
712
713
# File 'lib/rdf/model/list.rb', line 711

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[1, 2, 3]

Returns:

  • (Set)

Since:

  • 0.2.3



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

def to_set
  require 'set' unless defined?(::Set)
  each.to_set
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



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

def uniq
  RDF::List[*to_a.uniq]
end

#valid?Boolean

Validate the list ensuring that

  • rdf:rest values are all BNodes are nil

  • rdf:type, if it exists, is rdf:List

  • each subject has no properties other than single-valued rdf:first, rdf:rest other than for the first node in the list

Returns:

  • (Boolean)

Since:

  • 0.2.3



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rdf/model/list.rb', line 66

def valid?
  li = subject
  while li != RDF.nil do
    rest = nil
    firsts = rests = 0
    @graph.query(:subject => li) do |st|
      case st.predicate
      when RDF.type
        # Be tollerant about rdf:type entries, as some OWL vocabularies use it excessively
      when RDF.first
        firsts += 1
      when RDF.rest
        rest = st.object
        return false unless rest.node? || rest == RDF.nil
        rests += 1
      else
        # First node may have other properties
        return false unless li == subject
      end
    end
    return false unless firsts == 1 && rests == 1
    li = rest
  end
  true
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



137
138
139
# File 'lib/rdf/model/list.rb', line 137

def |(other)
  RDF::List[*(to_a | other.to_a)]
end