Class: Alf::Aggregator
- Inherits:
-
Object
- Object
- Alf::Aggregator
- Extended by:
- Support::Registry
- Defined in:
- lib/alf-aggregator/alf/aggregator.rb,
lib/alf-aggregator/alf/aggregator/avg.rb,
lib/alf-aggregator/alf/aggregator/max.rb,
lib/alf-aggregator/alf/aggregator/min.rb,
lib/alf-aggregator/alf/aggregator/sum.rb,
lib/alf-aggregator/alf/aggregator/count.rb,
lib/alf-aggregator/alf/aggregator/concat.rb,
lib/alf-aggregator/alf/aggregator/stddev.rb,
lib/alf-aggregator/alf/aggregator/collect.rb,
lib/alf-aggregator/alf/aggregator/variance.rb
Overview
Aggregation operator.
This class provides a basis for implementing aggregation operators. It should always be used as a superclass for such implementations.
Aggregation operators are made available through factory methods on the Aggregator class itself:
Aggregator.count
Aggregator.sum{ qty }
The coercion method should always be used for building aggregators from lispy source code:
Aggregator.coerce("count")
Aggregator.coerce("sum{ qty }")
Once built, aggregators can be used either in black-box or white-box modes.
relation = ...
agg = Aggregator.sum{ qty }
# Black box mode:
result = agg.aggregate(relation)
# White box mode:
memo = agg.least
relation.each do |tuple|
memo = agg.happens(memo, tuple)
end
result = agg.finalize(memo)
Defined Under Namespace
Classes: Avg, Collect, Concat, Count, Max, Min, Stddev, Sum, Variance
Instance Attribute Summary collapse
-
#functor ⇒ TupleExpression
readonly
The underlying functor.
-
#options ⇒ Hash
readonly
Aggregation options.
-
#source ⇒ String
Source code of the aggregator, if any.
Class Method Summary collapse
-
.coerce(arg) ⇒ Aggregator
Coerces ‘arg` to an Aggregator.
-
.inherited(clazz) ⇒ Object
Automatically installs factory methods for inherited classes.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Checks equality with another aggregator.
-
#aggregate(enum) ⇒ Object
Aggregates over an enumeration of tuples.
-
#default_options ⇒ Hash
Returns the default options to use.
-
#finalize(memo) ⇒ Object
This method finalizes an aggregation.
-
#happens(memo, scope) ⇒ Object
This method is called on each aggregated tuple and must return an updated memo value.
-
#has_source_code! ⇒ String
Asserts that this aggregator knows its source code or raises a NotImplementedError.
-
#infer_type ⇒ Object
Infers the resulting type from expression source code.
-
#initialize(options = {}, &block) ⇒ Aggregator
constructor
Creates an Aggregator instance.
-
#least ⇒ Object
Returns the least value, which is the one to use on an empty set.
-
#to_lispy ⇒ String
Returns a lispy expression.
Methods included from Support::Registry
each, listen, listeners, register, registered
Constructor Details
#initialize(options = {}, &block) ⇒ Aggregator
Creates an Aggregator instance.
Example:
Aggregator.new{ size * price }
105 106 107 108 109 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 105 def initialize( = {}, &block) , block = {}, if .is_a?(Symbol) && block.nil? = .merge() @functor = Support.coerce(block, TupleExpression) end |
Instance Attribute Details
#functor ⇒ TupleExpression (readonly)
Returns the underlying functor.
94 95 96 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 94 def functor @functor end |
#options ⇒ Hash (readonly)
Returns Aggregation options.
91 92 93 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 91 def end |
#source ⇒ String
Returns source code of the aggregator, if any.
97 98 99 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 97 def source @source end |
Class Method Details
.coerce(arg) ⇒ Aggregator
Coerces ‘arg` to an Aggregator
Implemented coercions are:
-
Aggregator -> self
-
String -> through factory methods on self
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 76 def coerce(arg) case arg when Aggregator arg when String agg = instance_eval(arg) agg.source = arg agg else raise ArgumentError, "Invalid arg `arg` for Aggregator()" end end |
.inherited(clazz) ⇒ Object
Automatically installs factory methods for inherited classes.
63 64 65 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 63 def inherited(clazz) register(clazz, Aggregator) end |
Instance Method Details
#==(other) ⇒ Boolean
Checks equality with another aggregator
196 197 198 199 200 201 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 196 def ==(other) return false unless other.is_a?(Aggregator) has_source_code! == other.has_source_code! rescue NotImplementedError super end |
#aggregate(enum) ⇒ Object
Aggregates over an enumeration of tuples.
161 162 163 164 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 161 def aggregate(enum) scope = Support::TupleScope.new finalize(enum.inject(least){|m,t| happens(m, scope.__set_tuple(t))}) end |
#default_options ⇒ Hash
Returns the default options to use
114 115 116 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 114 def {} end |
#finalize(memo) ⇒ Object
This method finalizes an aggregation.
Argument memo is either least or the result of aggregating through happens. The default implementation simply returns memo. The method is intended to be overriden for complex aggregations that need statefull information such as ‘avg`.
153 154 155 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 153 def finalize(memo) memo end |
#happens(memo, scope) ⇒ Object
This method is called on each aggregated tuple and must return an updated memo value. It can be seen as the block typically given to Enumerable.inject.
The default implementation collects the pre-value on the tuple and delegates to _happens.
139 140 141 142 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 139 def happens(memo, scope) raise unless Support::TupleScope===scope _happens(memo, @functor.evaluate(scope)) end |
#has_source_code! ⇒ String
Asserts that this aggregator knows its source code or raises a NotImplementedError.
175 176 177 178 179 180 181 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 175 def has_source_code! if source.nil? raise NotImplementedError, "No known source code for this aggregator" else source end end |
#infer_type ⇒ Object
Infers the resulting type from expression source code
167 168 169 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 167 def infer_type Object end |
#least ⇒ Object
Returns the least value, which is the one to use on an empty set.
This method is intended to be overriden by subclasses; default implementation returns nil.
125 126 127 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 125 def least nil end |
#to_lispy ⇒ String
Returns a lispy expression
186 187 188 189 190 |
# File 'lib/alf-aggregator/alf/aggregator.rb', line 186 def to_lispy has_source_code! rescue NotImplementedError "[lispy code unavailable]" end |