Module: RDF::Enumerable

Extended by:
Util::Aliasing::LateBound
Includes:
Enumerable, Countable
Included in:
Dataset, Enumerator, Graph, List, Query, Query::Solution, Queryable::Enumerator, Reader, Transaction
Defined in:
lib/rdf/mixin/enumerable.rb,
lib/rdf/mixin/enumerator.rb

Overview

Enumerators for different mixins. These are defined in a separate module, so that they are bound when used, allowing other mixins inheriting behavior to be included.

Defined Under Namespace

Classes: Enumerator

Instance Method Summary collapse

Methods included from Util::Aliasing::LateBound

alias_method

Methods included from Countable

#count, #empty?

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#String

Implements #to_writer for each available instance of Writer, based on the writer symbol.

See Also:

  • RDF::Enumerable.{RDF{RDF::Writer{RDF::Writer.sym}


755
756
757
758
759
760
761
762
# File 'lib/rdf/mixin/enumerable.rb', line 755

def method_missing(meth, *args)
  writer = RDF::Writer.for(meth.to_s[3..-1].to_sym) if meth.to_s[0,3] == "to_"
  if writer
    writer.buffer(standard_prefixes: true) {|w| w << self}
  else
    super
  end
end

Instance Method Details

#dump(*args) ⇒ String

Returns a serialized string representation of ‘self`.

Before calling this method you may need to explicitly require a serialization extension for the specified format.

Examples:

Serializing into N-Triples format

require 'rdf/ntriples'
ntriples = enumerable.dump(:ntriples)

Raises:

See Also:

Since:

  • 0.2.0



741
742
743
744
745
746
# File 'lib/rdf/mixin/enumerable.rb', line 741

def dump(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  writer = RDF::Writer.for(*args)
  raise RDF::WriterError, "No writer found using #{args.inspect}" unless writer
  writer.dump(self, nil, options)
end

#each_graph {|graph| ... } ⇒ void #each_graphEnumerator<RDF::Graph>

Iterates the given block for each RDF graph in ‘self`.

If no block was given, returns an enumerator.

The order in which graphs are yielded is undefined.

Overloads:

  • #each_graph {|graph| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (graph)

      each graph

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:

Since:

  • 0.1.9



659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/rdf/mixin/enumerable.rb', line 659

def each_graph
  if block_given?
    yield RDF::Graph.new(graph_name: nil, data: self)
    # FIXME: brute force, repositories should override behavior
    if supports?(:graph_name)
      enum_statement.map(&:graph_name).uniq.compact.each do |graph_name|
        yield RDF::Graph.new(graph_name: graph_name, data: self)
      end
    end
  end
  enum_graph
end

#each_object {|object| ... } ⇒ void #each_objectEnumerator<RDF::Term>

Iterates the given block for each unique RDF object term.

If no block was given, returns an enumerator.

The order in which values are yielded is undefined.

Overloads:

  • #each_object {|object| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (object)

      each object term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



475
476
477
478
479
480
481
482
483
484
485
486
487
# File 'lib/rdf/mixin/enumerable.rb', line 475

def each_object # FIXME: deduplication
  if block_given?
    values = {}
    each_statement do |statement|
      value = statement.object
      unless value.nil? || values.include?(value)
        values[value] = true
        yield value
      end
    end
  end
  enum_object
end

#each_predicate {|predicate| ... } ⇒ void #each_predicateEnumerator<RDF::URI>

Iterates the given block for each unique RDF predicate term.

If no block was given, returns an enumerator.

The order in which values are yielded is undefined.

Overloads:

  • #each_predicate {|predicate| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (predicate)

      each predicate term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/rdf/mixin/enumerable.rb', line 409

def each_predicate
  if block_given?
    values = {}
    each_statement do |statement|
      value = statement.predicate
      unless value.nil? || values.include?(value.to_s)
        values[value.to_s] = true
        yield value
      end
    end
  end
  enum_predicate
end

#each_quad {|subject, predicate, object, graph_name| ... } ⇒ void #each_quadEnumerator<Array(RDF::Resource, RDF::URI, RDF::Term, RDF::Resource)>

Iterates the given block for each RDF quad.

If no block was given, returns an enumerator.

The order in which quads are yielded is undefined.

Overloads:

  • #each_quad {|subject, predicate, object, graph_name| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (subject, predicate, object, graph_name)

      each quad

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



282
283
284
285
286
287
288
289
# File 'lib/rdf/mixin/enumerable.rb', line 282

def each_quad
  if block_given?
    each_statement do |statement|
      yield *statement.to_quad
    end
  end
  enum_quad
end

#each_statement {|statement| ... } ⇒ void #each_statementEnumerator<RDF::Statement>

Iterates the given block for each RDF statement.

If no block was given, returns an enumerator.

The order in which statements are yielded is undefined.

Overloads:

  • #each_statement {|statement| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (statement)

      each statement

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



156
157
158
159
160
161
162
# File 'lib/rdf/mixin/enumerable.rb', line 156

def each_statement(&block)
  if block_given?
    # Invoke {#each} in the containing class:
    each(&block)
  end
  enum_statement
end

#each_subject {|subject| ... } ⇒ void #each_subjectEnumerator<RDF::Resource>

Iterates the given block for each unique RDF subject term.

If no block was given, returns an enumerator.

The order in which values are yielded is undefined.

Overloads:

  • #each_subject {|subject| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (subject)

      each subject term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/rdf/mixin/enumerable.rb', line 344

def each_subject
  if block_given?
    values = {}
    each_statement do |statement|
      value = statement.subject
      unless value.nil? || values.include?(value.to_s)
        values[value.to_s] = true
        yield value
      end
    end
  end
  enum_subject
end

#each_term {|term| ... } ⇒ void #each_termEnumerator<RDF::Term>

Iterates the given block for each unique RDF term (subject, predicate, object, or graph_name).

If no block was given, returns an enumerator.

The order in which values are yielded is undefined.

Overloads:

  • #each_term {|term| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (term)

      each term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:

Since:

  • 2.0



549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'lib/rdf/mixin/enumerable.rb', line 549

def each_term
  if block_given?
    values = {}
    each_statement do |statement|
      statement.to_quad.each do |value|
        unless value.nil? || values.include?(value.hash)
          values[value.hash] = true
          yield value
        end
      end
    end
  end
  enum_term
end

#each_triple {|subject, predicate, object| ... } ⇒ void #each_tripleEnumerator<Array(RDF::Resource, RDF::URI, RDF::Term)>

Iterates the given block for each RDF triple.

If no block was given, returns an enumerator.

The order in which triples are yielded is undefined.

Overloads:

  • #each_triple {|subject, predicate, object| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (subject, predicate, object)

      each triple

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:



220
221
222
223
224
225
226
227
# File 'lib/rdf/mixin/enumerable.rb', line 220

def each_triple
  if block_given?
    each_statement do |statement|
      yield *statement.to_triple
    end
  end
  enum_triple
end

#enum_for(method = :each, *args) ⇒ Enumerator Also known as: to_enum

See Also:

  • Object#enum_for


778
779
780
781
782
783
784
# File 'lib/rdf/mixin/enumerable.rb', line 778

def enum_for(method = :each, *args)
  # Ensure that enumerators are, themselves, queryable
  this = self
  Enumerable::Enumerator.new do |yielder|
    this.send(method, *args) {|*y| yielder << (y.length > 1 ? y : y.first)}
  end
end

#enum_graphEnumerator<RDF::Graph> Also known as: enum_graphs

Returns an enumerator for #each_graph.

See Also:

Since:

  • 0.1.9



678
679
680
# File 'lib/rdf/mixin/enumerable.rb', line 678

def enum_graph
  enum_for(:each_graph)
end

#enum_objectEnumerator<RDF::Term> Also known as: enum_objects

Returns an enumerator for #each_object.

See Also:



494
495
496
# File 'lib/rdf/mixin/enumerable.rb', line 494

def enum_object
  enum_for(:each_object)
end

#enum_predicateEnumerator<RDF::URI> Also known as: enum_predicates

Returns an enumerator for #each_predicate.

See Also:



428
429
430
# File 'lib/rdf/mixin/enumerable.rb', line 428

def enum_predicate
  enum_for(:each_predicate)
end

#enum_quadEnumerator<Array(RDF::Resource, RDF::URI, RDF::Term, RDF::Resource)> Also known as: enum_quads

Returns an enumerator for #each_quad.

See Also:



296
297
298
299
300
# File 'lib/rdf/mixin/enumerable.rb', line 296

def enum_quad
  Countable::Enumerator.new do |yielder|
    each_quad {|s, p, o, c| yielder << [s, p, o, c]}
  end
end

#enum_statementEnumerator<RDF::Statement> Also known as: enum_statements

Returns an enumerator for #each_statement. FIXME: enum_for doesn’t seem to be working properly in JRuby 1.7, so specs are marked pending

See Also:



171
172
173
174
175
176
177
# File 'lib/rdf/mixin/enumerable.rb', line 171

def enum_statement
  # Ensure that statements are queryable, countable and enumerable
  this = self
  Queryable::Enumerator.new do |yielder|
    this.send(:each_statement) {|y| yielder << y}
  end
end

#enum_subjectEnumerator<RDF::Resource> Also known as: enum_subjects

Returns an enumerator for #each_subject.

See Also:



363
364
365
# File 'lib/rdf/mixin/enumerable.rb', line 363

def enum_subject
  enum_for(:each_subject)
end

#enum_termEnumerator<RDF::Term> Also known as: enum_terms

Returns an enumerator for #each_term.

See Also:

Since:

  • 2.0



570
571
572
# File 'lib/rdf/mixin/enumerable.rb', line 570

def enum_term
  enum_for(:each_term)
end

#enum_tripleEnumerator<Array(RDF::Resource, RDF::URI, RDF::Term)> Also known as: enum_triples

Returns an enumerator for #each_triple.

See Also:



234
235
236
237
238
# File 'lib/rdf/mixin/enumerable.rb', line 234

def enum_triple
  Countable::Enumerator.new do |yielder|
    each_triple {|s, p, o| yielder << [s, p, o]}
  end
end

#graph_names(unique: true) ⇒ Array<RDF::Resource>

Returns all unique RDF graph names, other than the default graph.

See Also:

Since:

  • 2.0



583
584
585
586
587
588
589
# File 'lib/rdf/mixin/enumerable.rb', line 583

def graph_names(unique: true)
  unless unique
    enum_statement.map(&:graph_name).compact # TODO: optimize
  else
    enum_graph.map(&:graph_name).compact
  end
end

#has_graph?(graph_name) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF graph_name.



597
598
599
# File 'lib/rdf/mixin/enumerable.rb', line 597

def has_graph?(graph_name)
  enum_statement.any? {|s| s.graph_name == graph_name}
end

#has_object?(value) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF object term.



453
454
455
# File 'lib/rdf/mixin/enumerable.rb', line 453

def has_object?(value)
  enum_object.include?(value)
end

#has_predicate?(value) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF predicate term.



388
389
390
# File 'lib/rdf/mixin/enumerable.rb', line 388

def has_predicate?(value)
  enum_predicate.include?(value)
end

#has_quad?(quad) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF quad.



257
258
259
# File 'lib/rdf/mixin/enumerable.rb', line 257

def has_quad?(quad)
  quads.include?(quad)
end

#has_statement?(statement) ⇒ Boolean Also known as: include?

Returns ‘true` if `self` contains the given RDF statement.



133
134
135
# File 'lib/rdf/mixin/enumerable.rb', line 133

def has_statement?(statement)
  !enum_statement.find { |s| s.eql?(statement) }.nil?
end

#has_subject?(value) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF subject term.



323
324
325
# File 'lib/rdf/mixin/enumerable.rb', line 323

def has_subject?(value)
  enum_subject.include?(value)
end

#has_term?(value) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF subject term.

Since:

  • 2.0



527
528
529
# File 'lib/rdf/mixin/enumerable.rb', line 527

def has_term?(value)
  enum_term.include?(value)
end

#has_triple?(triple) ⇒ Boolean

Returns ‘true` if `self` contains the given RDF triple.



196
197
198
# File 'lib/rdf/mixin/enumerable.rb', line 196

def has_triple?(triple)
  triples.include?(triple)
end

#invalid?Boolean

Returns ‘true` if value is not valid

Raises:

  • (NotImplementedError)

    unless enumerable supports validation

Since:

  • 0.2.1



102
103
104
# File 'lib/rdf/mixin/enumerable.rb', line 102

def invalid?
  !valid?
end

#objects(unique: true) ⇒ Array<RDF::Term>

Returns all unique RDF object terms.



440
441
442
443
444
445
446
# File 'lib/rdf/mixin/enumerable.rb', line 440

def objects(unique: true)
  unless unique
    enum_statement.map(&:object) # TODO: optimize
  else
    Array(enum_object)
  end
end

#predicates(unique: true) ⇒ Array<RDF::URI>

Returns all unique RDF predicate terms.



375
376
377
378
379
380
381
# File 'lib/rdf/mixin/enumerable.rb', line 375

def predicates(unique: true)
  unless unique
    enum_statement.map(&:predicate) # TODO: optimize
  else
    Array(enum_predicate)
  end
end

#project_graph(graph_name) {|statement| ... } ⇒ void #project_graph(graph_name) ⇒ Enumerable

Limits statements to be from a specific graph.

If no block was given, returns an enumerator.

The order in which statements are yielded is undefined.

Overloads:

  • #project_graph(graph_name) {|statement| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (statement)

      each statement

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

See Also:

Since:

  • 3.0



626
627
628
629
630
631
632
633
634
635
636
637
638
# File 'lib/rdf/mixin/enumerable.rb', line 626

def project_graph(graph_name)
  if block_given?
    self.each do |statement|
      yield statement if statement.graph_name == graph_name
    end
  else
    # Ensure that statements are queryable, countable and enumerable
    this = self
    Queryable::Enumerator.new do |yielder|
      this.send(:project_graph, graph_name) {|y| yielder << y}
    end
  end
end

#quads(options = {}) ⇒ Array<Array(RDF::Resource, RDF::URI, RDF::Term, RDF::Resource)>

Returns all RDF quads.



248
249
250
# File 'lib/rdf/mixin/enumerable.rb', line 248

def quads(options = {})
  enum_statement.map(&:to_quad) # TODO: optimize
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Note:

this instantiates an writer; it could probably be done more efficiently by refactoring ‘RDF::Reader` and/or `RDF::Format` to expose a list of valid format symbols.



768
769
770
771
# File 'lib/rdf/mixin/enumerable.rb', line 768

def respond_to_missing?(name, include_private = false)
  return RDF::Writer.for(name.to_s[3..-1].to_sym) if name.to_s[0,3] == 'to_'
  super
end

#statements(options = {}) ⇒ Array<RDF::Statement>

Returns all RDF statements.



124
125
126
# File 'lib/rdf/mixin/enumerable.rb', line 124

def statements(options = {})
  Array(enum_statement)
end

#subjects(unique: true) ⇒ Array<RDF::Resource>

Returns all unique RDF subject terms.



310
311
312
313
314
315
316
# File 'lib/rdf/mixin/enumerable.rb', line 310

def subjects(unique: true)
  unless unique
    enum_statement.map(&:subject) # TODO: optimize
  else
    Array(enum_subject)
  end
end

#supports?(feature) ⇒ Boolean

Returns ‘true` if this enumerable supports the given `feature`.

Supported features include:

* `:graph_name` supports statements with a graph_name, allowing multiple named graphs
* `:inference` supports RDFS inferrence of queryable contents.
* `:literal_equality' preserves [term-equality](https://www.w3.org/TR/rdf11-concepts/#dfn-literal-term-equality) for literals. Literals are equal only if their lexical values and datatypes are equal, character by character. Literals may be "inlined" to value-space for efficiency only if `:literal_equality` is `false`.
* `:validity` allows a concrete Enumerable implementation to indicate that it does or does not support valididty checking. By default implementations are assumed to support validity checking.
* `:skolemize` supports [Skolemization](https://www.w3.org/wiki/BnodeSkolemization) of an `Enumerable`. Implementations supporting this feature must implement a `#skolemize` method, taking a base URI used for minting URIs for BNodes as stable identifiers and a `#deskolemize` method, also taking a base URI used for turning URIs having that prefix back into the same BNodes which were originally skolemized.

Since:

  • 0.3.5



78
79
80
# File 'lib/rdf/mixin/enumerable.rb', line 78

def supports?(feature)
  feature == :validity || feature == :literal_equality
end

#terms(unique: true) ⇒ Array<RDF::Resource>

Returns all unique RDF terms (subjects, predicates, objects, and graph_names).

Examples:

finding all Blank Nodes used within an enumerable

enumberable.terms.select(&:node?)

See Also:

  • #each_resource
  • #enum_resource

Since:

  • 2.0



510
511
512
513
514
515
516
517
518
519
# File 'lib/rdf/mixin/enumerable.rb', line 510

def terms(unique: true)
  unless unique
    enum_statement.
      map(&:to_quad).
      flatten.
      compact
  else
    Array(enum_term)
  end
end

#to_aArray

Returns all RDF statements in ‘self` as an array.

Mixes in ‘RDF::Enumerable` into the returned object.

Since:

  • 0.2.0



690
691
692
# File 'lib/rdf/mixin/enumerable.rb', line 690

def to_a
  super.extend(RDF::Enumerable)
end

#to_hashHash

Returns all RDF object terms indexed by their subject and predicate terms.

The return value is a ‘Hash` instance that has the structure: `=> {predicate => [*objects]}`.



714
715
716
717
718
719
720
721
722
# File 'lib/rdf/mixin/enumerable.rb', line 714

def to_hash
  result = {}
  each_statement do |statement|
    result[statement.subject] ||= {}
    values = (result[statement.subject][statement.predicate] ||= [])
    values << statement.object unless values.include?(statement.object)
  end
  result
end

#to_setSet

Returns all RDF statements in ‘self` as a set.

Mixes in ‘RDF::Enumerable` into the returned object.

Since:

  • 0.2.0



701
702
703
704
# File 'lib/rdf/mixin/enumerable.rb', line 701

def to_set
  require 'set' unless defined?(::Set)
  super.extend(RDF::Enumerable)
end

#triples(options = {}) ⇒ Array<Array(RDF::Resource, RDF::URI, RDF::Term)>

Returns all RDF triples.



187
188
189
# File 'lib/rdf/mixin/enumerable.rb', line 187

def triples(options = {})
  enum_statement.map(&:to_triple) # TODO: optimize
end

#valid?Boolean

Returns ‘true` if all statements are valid

Raises:

  • (NotImplementedError)

    unless enumerable supports validation

Since:

  • 0.3.11



88
89
90
91
92
93
94
# File 'lib/rdf/mixin/enumerable.rb', line 88

def valid?
  raise NotImplementedError, "#{self.class} does not support validation" unless supports?(:validity)
  each_statement do |s|
    return false if s.invalid?
  end
  true
end

#validate!RDF::Enumerable Also known as: validate

Default validate! implementation, overridden in concrete classes

Raises:

  • (ArgumentError)

    if the value is invalid

Since:

  • 0.3.9



111
112
113
114
# File 'lib/rdf/mixin/enumerable.rb', line 111

def validate!
  raise ArgumentError if supports?(:validity) && invalid?
  self
end