Class: ShEx::Algebra::Operator Abstract

Inherits:
Object
  • Object
show all
Extended by:
SPARQL::Algebra::Expression
Includes:
RDF::Util::Logger
Defined in:
lib/shex/algebra/operator.rb

Overview

This class is abstract.

The ShEx operator.

Defined Under Namespace

Classes: Binary, Unary

Constant Summary collapse

ARITY =

variable arity

-1 # variable arity

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*operands) ⇒ Operator #initialize(*operands, options) ⇒ Operator

Initializes a new operator instance.

Overloads:

  • #initialize(*operands) ⇒ Operator

    Parameters:

    • operands (Array<RDF::Term>)
  • #initialize(*operands, options) ⇒ Operator

    Parameters:

    • operands (Array<RDF::Term>)
    • options (Hash{Symbol => Object})

      any additional options

    Options Hash (options):

    • :memoize (Boolean) — default: false

      whether to memoize results for particular operands

Raises:

  • (TypeError)

    if any operand is invalid



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/shex/algebra/operator.rb', line 35

def initialize(*operands)
  @options  = operands.last.is_a?(Hash) ? operands.pop.dup : {}
  @operands = operands.map! do |operand|
    case operand
      when Array
        operand.each do |op|
          op.parent = self if op.respond_to?(:parent=)
        end
        operand
      when Operator, RDF::Term, RDF::Query, RDF::Query::Pattern, Array, Symbol
        operand.parent = self if operand.respond_to?(:parent=)
        operand
      when TrueClass, FalseClass, Numeric, String, DateTime, Date, Time
        RDF::Literal(operand)
      when NilClass
        raise ArgumentError, "Found nil operand for #{self.class.name}"
      else raise TypeError, "invalid ShEx::Algebra::Operator operand: #{operand.inspect}"
    end
  end

  if options[:logger]
    options[:depth] = 0
    each_descendant(1) do |depth, operand|
      if operand.respond_to?(:options)
        operand.options[:logger] = options[:logger]
        operand.options[:depth] = depth
      end
    end
  end
end

Instance Attribute Details

#operandsArray (readonly)

The operands to this operator.

Returns:

  • (Array)


118
119
120
# File 'lib/shex/algebra/operator.rb', line 118

def operands
  @operands
end

#optionsObject

Initialization options



18
19
20
# File 'lib/shex/algebra/operator.rb', line 18

def options
  @options
end

#schemaObject

Location of schema including this operator



15
16
17
# File 'lib/shex/algebra/operator.rb', line 15

def schema
  @schema
end

Instance Method Details

#closed?Boolean

Is this shape closed?

Returns:

  • (Boolean)


69
70
71
# File 'lib/shex/algebra/operator.rb', line 69

def closed?
  operands.include?(:closed)
end

#each_descendant(depth = 0) {|operator| ... } ⇒ Enumerator Also known as: descendants, each

Enumerate via depth-first recursive descent over operands, yielding each operator

Parameters:

  • depth (Integer) (defaults to: 0)

    incrementeded for each depth of operator, and provided to block if Arity is 2

Yields:

  • operator

Yield Parameters:

  • operator (Object)

Returns:

  • (Enumerator)


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/shex/algebra/operator.rb', line 177

def each_descendant(depth = 0, &block)
  if block_given?
    operands.each do |operand|
      case operand
      when Array
        operand.each do |op|
          op.each_descendant(depth + 1, &block) if op.respond_to?(:each_descendant)
        end
      else
        operand.each_descendant(depth + 1, &block) if operand.respond_to?(:each_descendant)
      end

      case block.arity
      when 1 then block.call(operand)
      else block.call(depth, operand)
      end
    end
  end
  enum_for(:each_descendant)
end

#eql?(other) ⇒ Boolean Also known as: ==

Parameters:

  • other (Statement)

Returns:

  • (Boolean)


166
167
168
# File 'lib/shex/algebra/operator.rb', line 166

def eql?(other)
  other.class == self.class && other.operands == self.operands
end

#first_ancestor(klass) ⇒ Operator

First ancestor operator of type ‘klass`

Parameters:

  • klass (Class)

Returns:



219
220
221
# File 'lib/shex/algebra/operator.rb', line 219

def first_ancestor(klass)
  parent.is_a?(klass) ? parent : parent.first_ancestor(klass) if parent
end

#inspectString

Returns a developer-friendly representation of this operator.

Returns:

  • (String)


159
160
161
# File 'lib/shex/algebra/operator.rb', line 159

def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, operands.to_sse.gsub(/\s+/m, ' '))
end

#not_matched(message, **opts) ⇒ Object

Exception handling



91
92
93
94
95
# File 'lib/shex/algebra/operator.rb', line 91

def not_matched(message, **opts)
  expression = opts.fetch(:expression, self)
  exception = opts.fetch(:exception, NotMatched)
  log_error(message, depth: options.fetch(:depth, 0), exception: exception) {"expression: #{expression.to_sxp}"}
end

#not_satisfied(message, **opts) ⇒ Object



97
98
99
100
101
# File 'lib/shex/algebra/operator.rb', line 97

def not_satisfied(message, **opts)
  expression = opts.fetch(:expression, self)
  exception = opts.fetch(:exception, ShEx::NotSatisfied)
  log_error(message, depth: options.fetch(:depth, 0), exception: exception) {"expression: #{expression.to_sxp}"}
end

#operand(index = 0) ⇒ RDF::Term

Returns the operand at the given ‘index`.

Parameters:

  • index (Integer) (defaults to: 0)

    an operand index in the range ‘(0…(operands.count))`

Returns:

  • (RDF::Term)


126
127
128
# File 'lib/shex/algebra/operator.rb', line 126

def operand(index = 0)
  operands[index]
end

#parentOperator

Parent expression, if any

Returns:



204
# File 'lib/shex/algebra/operator.rb', line 204

def parent; @options[:parent]; end

#parent=(operator) ⇒ Operator

Parent operator, if any

Returns:



210
211
212
# File 'lib/shex/algebra/operator.rb', line 210

def parent=(operator)
  @options[:parent]= operator
end

#satisfiable?Boolean

Does this operator include Satisfiable?

Returns:

  • (Boolean)


81
# File 'lib/shex/algebra/operator.rb', line 81

def satisfiable?; false; end

#semact?Boolean

Does this operator a SemAct?

Returns:

  • (Boolean)


87
# File 'lib/shex/algebra/operator.rb', line 87

def semact?; false; end

#semantic_actionsArray<SemAct>

Semantic Actions

Returns:



76
77
78
# File 'lib/shex/algebra/operator.rb', line 76

def semantic_actions
  operands.select {|o| o.is_a?(SemAct)}
end

#status(message, &block) ⇒ Object



109
110
111
112
# File 'lib/shex/algebra/operator.rb', line 109

def status(message, &block)
  log_info(self.class.const_get(:NAME), message, depth: options.fetch(:depth, 0), &block)
  true
end

#structure_error(message, **opts) ⇒ Object



103
104
105
106
107
# File 'lib/shex/algebra/operator.rb', line 103

def structure_error(message, **opts)
  expression = opts.fetch(:expression, self)
  exception = opts.fetch(:exception, ShEx::StructureError)
  log_error(message, depth: options.fetch(:depth, 0), exception: exception) {"expression: #{expression.to_sxp}"}
end

#to_sxpString

Returns an S-Expression (SXP) representation of this operator

Returns:

  • (String)


144
145
146
147
148
149
150
151
152
153
# File 'lib/shex/algebra/operator.rb', line 144

def to_sxp
  begin
    require 'sxp' # @see http://rubygems.org/gems/sxp
  rescue LoadError
    abort "SPARQL::Algebra::Operator#to_sxp requires the SXP gem (hint: `gem install sxp')."
  end
  require 'sparql/algebra/sxp_extensions'

  to_sxp_bin.to_sxp
end

#to_sxp_binArray

Returns the SPARQL S-Expression (SSE) representation of this operator.

Returns:

  • (Array)

See Also:



135
136
137
138
# File 'lib/shex/algebra/operator.rb', line 135

def to_sxp_bin
  operator = [self.class.const_get(:NAME)].flatten.first
  [operator, *(operands || []).map(&:to_sxp_bin)]
end

#triple_expression?Boolean

Does this operator include TripleExpression?

Returns:

  • (Boolean)


84
# File 'lib/shex/algebra/operator.rb', line 84

def triple_expression?; false; end

#validate!SPARQL::Algebra::Expression

Validate all operands, operator specific classes should override for operator-specific validation

Returns:

  • (SPARQL::Algebra::Expression)

    ‘self`

Raises:



227
228
229
230
# File 'lib/shex/algebra/operator.rb', line 227

def validate!
  operands.each {|op| op.validate! if op.respond_to?(:validate!)}
  self
end