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

#Hash (protected) #String (protected)

Overloads:

  • #Hash
    Deprecated.

    Use #to_h instead.

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

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

    Returns:

    • (Hash)
  • #String

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

    Returns:

    • (String)

    See Also:

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


765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/rdf/mixin/enumerable.rb', line 765

def method_missing(meth, *args)
  case meth
  when :to_hash
    warn "[DEPRECATION] RDF::Enumerable#to_hash is deprecated, use RDF::Enumerable#to_h instead.\n" +
         "This is due to the introduction of keyword arugments that attempt to turn the last argument into a hash using #to_hash.\n" +
         "This can be avoided by explicitly passing an options hash as the last argument.\n" +
         "Called from #{Gem.location_of_caller.join(':')}"
    return self.to_h
  end
  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, **options) ⇒ 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)

Parameters:

  • args (Array<Object>)

    if the last argument is a hash, it is passed as options to Writer.dump.

Returns:

  • (String)

Raises:

See Also:

Since:

  • 0.2.0



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

def dump(*args, **options)
  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| ... } #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:

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| ... } #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| ... }

    This method returns an undefined value.

    Yields:

    • (object)

      each object term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

  • #each_objectEnumerator<RDF::Term>

    Returns:

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| ... } #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| ... }

    This method returns an undefined value.

    Yields:

    • (predicate)

      each predicate term

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

  • #each_predicateEnumerator<RDF::URI>

    Returns:

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| ... } #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:

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| ... } #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:

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| ... } #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:

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| ... } #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:

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| ... } #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:

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_graphEnumerator<RDF::Graph> Also known as: enum_graphs

Returns an enumerator for #each_graph.

Returns:

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.

Returns:

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.

Returns:

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.



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

Returns:

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.

Returns:

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.

Returns:

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.

Returns:

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.

Parameters:

  • unique (true)

Returns:

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.

Parameters:

  • graph_name (RDF::Resource, false)

    Use value false to query for the default graph_name

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)


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.

Parameters:

Returns:

  • (Boolean)

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.

Parameters:

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)

    true or false

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.

Parameters:

  • unique (true)

Returns:

See Also:



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
    enum_object.to_a
  end
end

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

Returns all unique RDF predicate terms.

Parameters:

  • unique (true)

Returns:

See Also:



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
    enum_predicate.to_a
  end
end

#project_graph(graph_name) {|statement| ... } #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| ... }

    This method returns an undefined value.

    Parameters:

    • graph_name (RDF::Resource, nil)

      The name of the graph from which statements are taken. Use nil for the default graph.

    Yields:

    • (statement)

      each statement

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

  • #project_graph(graph_name) ⇒ Enumerable

    Parameters:

    • graph_name (RDF::Resource, false)

      The name of the graph from which statements are taken. Use false for the default graph.

    Returns:

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.

Parameters:

  • options (Hash{Symbol => Boolean})

Returns:

See Also:



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 (protected)

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.

Returns:

  • (Boolean)


786
787
788
789
# File 'lib/rdf/mixin/enumerable.rb', line 786

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.

Parameters:

  • options (Hash{Symbol => Boolean})

Returns:

See Also:



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

def statements(**options)
  enum_statement.to_a
end

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

Returns all unique RDF subject terms.

Parameters:

  • unique (true)

Returns:

See Also:



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
    enum_subject.to_a
  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_equalityisfalse`.
  • :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 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.

Parameters:

  • feature (Symbol, #to_sym)

Returns:

  • (Boolean)

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

Parameters:

  • unique (true)

Returns:

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
    enum_term.to_a
  end
end

#to_aArray

Returns all RDF statements in self as an array.

Mixes in RDF::Enumerable into the returned object.

Returns:

  • (Array)

Since:

  • 0.2.0



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

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

#to_hHash

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

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

Returns:

  • (Hash)


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

def to_h
  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.

Returns:

  • (Set)

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.

Parameters:

  • options (Hash{Symbol => Boolean})

Returns:

See Also:



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

Returns:

  • (Boolean)

    true or false

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

Returns:

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