class RDF::Query::Solution

An RDF query solution.

@example Iterating over every binding in the solution

solution.each_binding  { |name, value| puts value.inspect }
solution.each_variable { |variable| puts variable.value.inspect }

@example Iterating over every value in the solution

solution.each_value    { |value| puts value.inspect }

@example Checking whether a variable is bound or unbound

solution.bound?(:title)
solution.unbound?(:mbox)

@example Retrieving the value of a bound variable

solution[:mbox]
solution.mbox

@example Retrieving all bindings in the solution as a ‘Hash`

solution.to_h       #=> {mbox: "jrhacker@example.org", ...}

Constants

INSTANCE_METHODS

Temporarily remember instance method for deprecation message in ‘method_missing`.

Attributes

bindings[R]

@private

Public Class Methods

new(bindings = {}, &block) click to toggle source

Initializes the query solution.

@param [Hash{Symbol => RDF::Term}] bindings @yield [solution]

# File lib/rdf/query/solution.rb, line 42
def initialize(bindings = {}, &block)
  @bindings = bindings.to_h

  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

Equals of solution

# File lib/rdf/query/solution.rb, line 329
def ==(other)
  other.is_a?(Solution) && @bindings == other.bindings
end
[](name) click to toggle source

Returns the value of the variable ‘name`.

@param [Symbol, to_sym] name

the variable name

@return [RDF::Term]

# File lib/rdf/query/solution.rb, line 192
def [](name)
  @bindings[name.to_sym]
end
[]=(name, value) click to toggle source

Binds or rebinds the variable ‘name` to the given `value`.

@param [Symbol, to_sym] name

the variable name

@param [RDF::Term] value @return [RDF::Term] @since 0.3.0

# File lib/rdf/query/solution.rb, line 204
def []=(name, value)
  @bindings[name.to_sym] = value.is_a?(RDF::Term) ? value : RDF::Literal(value)
end
bound?(name) click to toggle source

Returns ‘true` if the variable `name` is bound in this solution.

@param [Symbol, to_sym] name

the variable name

@return [Boolean] ‘true` or `false`

# File lib/rdf/query/solution.rb, line 172
def bound?(name)
  !unbound?(name)
end
compatible?(other) click to toggle source

Compatible Mappings

Two solution mappings u1 and u2 are compatible if, for every variable v in dom(u1) and in dom(u2), u1(v) = u2(v).

@param [RDF::Query::Solution, to_h] other

another query solution or hash bindings

@return [Boolean] @see www.w3.org/TR/2013/REC-sparql11-query-20130321/#defn_algCompatibleMapping

# File lib/rdf/query/solution.rb, line 268
def compatible?(other)
  @bindings.all? do |k, v|
    !other.to_h.key?(k) || other[k].eql?(v)
  end
end
disjoint?(other) click to toggle source

Disjoint mapping

A solution is disjoint with another solution if it shares no common variables in their domains.

@param [RDF::Query::Solution] other @return [Boolean] @see www.w3.org/TR/2013/REC-sparql11-query-20130321/#defn_algMinus

# File lib/rdf/query/solution.rb, line 282
def disjoint?(other)
  @bindings.none? do |k, v|
    v && other.to_h.key?(k) && other[k].eql?(v)
  end
end
dup() click to toggle source

Duplicate solution, preserving patterns @return [RDF::Statement]

# File lib/rdf/query/solution.rb, line 255
def dup
  merge({})
end
each(&block)
Alias for: each_binding
each_binding(&block) click to toggle source

Enumerates over every variable binding in this solution.

@yield [name, value] @yieldparam [Symbol] name @yieldparam [RDF::Term] value @return [Enumerator]

# File lib/rdf/query/solution.rb, line 63
def each_binding(&block)
  @bindings.each(&block) if block_given?
  enum_binding
end
Also aliased as: each
each_key(&block)
Alias for: each_name
each_name(&block) click to toggle source

Enumerates over every variable name in this solution.

@yield [name] @yieldparam [Symbol] name @return [Enumerator]

# File lib/rdf/query/solution.rb, line 84
def each_name(&block)
  @bindings.each_key(&block) if block_given?
  enum_name
end
Also aliased as: each_key
each_value(&block) click to toggle source

Enumerates over every variable value in this solution.

@yield [value] @yieldparam [RDF::Term] value @return [Enumerator]

# File lib/rdf/query/solution.rb, line 105
def each_value(&block)
  @bindings.each_value(&block) if block_given?
  enum_value
end
each_variable() { |variable| ... } click to toggle source

Enumerates over every variable in this solution.

@yield [variable] @yieldparam [Variable] @return [Enumerator]

# File lib/rdf/query/solution.rb, line 148
def each_variable
  if block_given?
    @bindings.each do |name, value|
      yield Variable.new(name, value)
    end
  end
  enum_variable
end
enum_binding() click to toggle source

Returns an enumerator for {#each_binding}.

@return [Enumerator<RDF::Resource>] @see each_subject

# File lib/rdf/query/solution.rb, line 74
def enum_binding
  enum_for(:each_binding)
end
enum_name() click to toggle source

Returns an enumerator for {#each_name}.

@return [Enumerator<RDF::Resource>] @see each_subject

# File lib/rdf/query/solution.rb, line 95
def enum_name
  enum_for(:each_name)
end
enum_value() click to toggle source

Returns an enumerator for {#each_value}.

@return [Enumerator<RDF::Resource>] @see each_subject

# File lib/rdf/query/solution.rb, line 115
def enum_value
  enum_for(:each_value)
end
enum_variable() click to toggle source

Returns an enumerator for {#each_variable}.

@return [Enumerator<RDF::Resource>] @see each_subject

# File lib/rdf/query/solution.rb, line 162
def enum_variable
  enum_for(:each_variable)
end
eql?(other) click to toggle source

Equivalence of solution

# File lib/rdf/query/solution.rb, line 323
def eql?(other)
  other.is_a?(Solution) && @bindings.eql?(other.bindings)
end
has_variables?(*args)
Alias for: variable?
hash() click to toggle source

Integer hash of this solution @return [Integer]

# File lib/rdf/query/solution.rb, line 317
def hash
  @bindings.hash
end
inspect() click to toggle source

@return [String]

# File lib/rdf/query/solution.rb, line 335
def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, @bindings.inspect)
end
isomorphic_with?(other) click to toggle source

Isomorphic Mappings Two solution mappings u1 and u2 are isomorphic if, for every variable v in dom(u1) and in dom(u2), u1(v) = u2(v).

@param [RDF::Query::Solution, to_h] other

another query solution or hash bindings

@return [Boolean]

# File lib/rdf/query/solution.rb, line 296
def isomorphic_with?(other)
  @bindings.all? do |k, v|
    !other.to_h.key?(k) || other[k].eql?(v)
  end
end
merge(other) click to toggle source

Merges the bindings from the given ‘other` query solution with a copy of this one.

@param [RDF::Query::Solution, to_h] other

another query solution or hash bindings

@return [RDF::Query::Solution] @since 0.3.0

# File lib/rdf/query/solution.rb, line 248
def merge(other)
  self.class.new(@bindings.dup).merge!(other)
end
merge!(other) click to toggle source

Merges the bindings from the given ‘other` query solution into this one, overwriting any existing ones having the same name.

## RDF-star

If merging a binding for a statement to a pattern, merge their embedded solutions.

@param [RDF::Query::Solution, to_h] other

another query solution or hash bindings

@return [void] self @since 0.3.0

# File lib/rdf/query/solution.rb, line 221
def merge!(other)
  @bindings.merge!(other.to_h) do |key, v1, v2|
    # Don't merge a pattern over a statement
    # This happens because JOIN does a reverse merge,
    # and a pattern is set in v2.
    v2.is_a?(Pattern) ? v1 : v2
  end
  # Merge bindings from patterns
  embedded_solutions = []
  @bindings.each do |k, v|
    if v.is_a?(Pattern) && other[k].is_a?(RDF::Statement)
      embedded_solutions << v.solution(other[k])
    end
  end
  # Merge embedded solutions
  embedded_solutions.each {|soln| merge!(soln)}
  self
end
to_a() click to toggle source

@return [Array<Array(Symbol, RDF::Term)>}

# File lib/rdf/query/solution.rb, line 304
def to_a
  @bindings.to_a
end
to_h() click to toggle source

@return [Hash{Symbol => RDF::Term}}

# File lib/rdf/query/solution.rb, line 310
def to_h
  @bindings.dup
end
unbound?(name) click to toggle source

Returns ‘true` if the variable `name` is unbound in this solution.

@param [Symbol, to_sym] name

the variable name

@return [Boolean] ‘true` or `false`

# File lib/rdf/query/solution.rb, line 182
def unbound?(name)
  @bindings[name.to_sym].nil?
end
variable?(*args) click to toggle source

@overload variable?

Returns `false`.

@return [Boolean]

@overload variable?(variables)

Returns `true` if this solution contains bindings for any of the given

‘variables`.

@param  [Array<Symbol, #to_sym>] variables
@return [Boolean]

@since 0.3.0

# File lib/rdf/query/solution.rb, line 131
def variable?(*args)
  case args.length
  when 0 then false
  when 1
    args.first.any? { |variable| bound?(variable) }
  else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
  end
end
Also aliased as: variables?, has_variables?
variables?(*args)
Alias for: variable?

Protected Instance Methods

enum_for(method = :each) click to toggle source

@private @param [Symbol, to_sym] method @return [Enumerator] @see Object#enum_for

# File lib/rdf/query/solution.rb, line 372
def enum_for(method = :each)
  # Ensure that enumerators are, themselves, queryable
  this = self
  Enumerator.new do |yielder|
    this.__send(method) {|*y| yielder << (y.length > 1 ? y : y.first)}
  end
end
Also aliased as: to_enum
method_missing(name, *args, &block) click to toggle source

@overload binding(name)

Return the binding for this name

@param  [Symbol] name
@return [RDF::Term]
Calls superclass method
# File lib/rdf/query/solution.rb, line 347
def method_missing(name, *args, &block)
  if args.empty? && @bindings.key?(name.to_sym)
    if INSTANCE_METHODS.include?(name)
      warn "[DEPRECATION] RDF::Query::Solution##{name} is an overridden instance method.\n" +
           "Its use as a solution accessor is deprecated and will be removed in a future version.\n" +
           "Use #[] for safe access.\n" +
           "Called from #{Gem.location_of_caller.join(':')}"
    end
    @bindings[name.to_sym]
  else
    super # raises NoMethodError
  end
end
respond_to_missing?(name, include_private = false) click to toggle source

@return [Boolean]

Calls superclass method
# File lib/rdf/query/solution.rb, line 363
def respond_to_missing?(name, include_private = false)
  @bindings.key?(name.to_sym) || super
end
to_enum(method = :each)
Alias for: enum_for