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
@private
Public Class Methods
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
Equals of solution
# File lib/rdf/query/solution.rb, line 329 def ==(other) other.is_a?(Solution) && @bindings == other.bindings end
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
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
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 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 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
Duplicate solution, preserving patterns @return [RDF::Statement]
# File lib/rdf/query/solution.rb, line 255 def dup merge({}) end
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
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
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
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
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
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
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
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
Equivalence of solution
# File lib/rdf/query/solution.rb, line 323 def eql?(other) other.is_a?(Solution) && @bindings.eql?(other.bindings) end
Integer hash of this solution @return [Integer]
# File lib/rdf/query/solution.rb, line 317 def hash @bindings.hash end
@return [String]
# File lib/rdf/query/solution.rb, line 335 def inspect sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, @bindings.inspect) end
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
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
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
@return [Array<Array(Symbol, RDF::Term
)>}
# File lib/rdf/query/solution.rb, line 304 def to_a @bindings.to_a end
@return [Hash{Symbol => RDF::Term
}}
# File lib/rdf/query/solution.rb, line 310 def to_h @bindings.dup end
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
@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
Protected Instance Methods
@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
@overload binding(name)
Return the binding for this name @param [Symbol] name @return [RDF::Term]
# 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
@return [Boolean]
# File lib/rdf/query/solution.rb, line 363 def respond_to_missing?(name, include_private = false) @bindings.key?(name.to_sym) || super end