File Coverage

blib/lib/App/RecordStream/DomainLanguage.pm
Criterion Covered Total %
statement 6 9 66.6
branch n/a
condition n/a
subroutine 2 5 40.0
pod 0 2 0.0
total 8 16 50.0


line stmt bran cond sub pod time code
1             package App::RecordStream::DomainLanguage;
2              
3 69     69   483 use strict;
  69         182  
  69         2219  
4 69     69   408 use warnings;
  69         357  
  69         14393  
5              
6             sub usage {
7 0     0 0   return "DOMAIN LANGUAGE\n" . short_usage() . _long_usage();
8             }
9              
10             sub short_usage {
11 0     0 0   return <
12             __FORMAT_TEXT__
13             The normal mechanism for specifying keys and aggregators allows one to
14             concisely instantiate the objects that back them in the platform and is
15             certainly the easiest way to use recs. The record stream domain language
16             allows the creation of these objects in a programmatic way, with neither the
17             syntactic issues of the normal way nor its guiding hand.
18              
19             The domain language is itself just Perl with a collection of library
20             functions for creating platform objects included. Your favorite aggregators
21             are all here with constructors matching their normal token. For convenience
22             of e.g. last, aggregators are also included with a prefixed underscore.
23              
24             Below you can find documentation on all the "built in" functions. Most
25             aggregators and deaggregators should be present with arguments comparable to
26             their normal instantiation arugments, but with keyspec parameters replaced
27             with valuations parameters.
28             __FORMAT_TEXT__
29             HELP
30             }
31              
32             sub _long_usage {
33 0     0     return <
34              
35             Special Syntax
36             __FORMAT_TEXT__
37             Where one sees a argument below, a string scalar is expected,
38             however quoting these can get fairly difficult and they can be confused with
39             non- scalars.
40              
41             Example:
42             __FORMAT_TEXT__
43             --dla "silly= uconcat(',', snip('{{x}} * 2'))"
44              
45             __FORMAT_TEXT__
46             To remedy this, one may use <> to inline a snippet which will be
47             immediately understood by the typing mechanism as being code. Escaping
48             inside this is as single quotes in Perl.
49              
50             Example With <>
51             __FORMAT_TEXT__
52             --dla 'silly= uconcat(",", <<{{x}} * 2>>)'
53              
54             __FORMAT_TEXT__
55             Furthermore one may mark variables to be propagated in by prefixing CODE
56             like <>:
57             __FORMAT_TEXT__
58             --dla 'silly= \$f=2; uconcat(",", <>)'
59              
60             Function Library
61             ii_agg(, [, ])
62             ii_aggregator(, [, ])
63             inject_into_agg(, [, ])
64             inject_into_aggregator(, [, ])
65             __FORMAT_TEXT__
66             Take an initial snippet, a combine snippet, and an optional squish
67             snippet to produce an ad-hoc aggregator based on inject into. The
68             initial snippet produces the aggregate value for an empty collection,
69             then combine takes \$a representing the aggregate value so far and \$r
70             representing the next record to add and returns the new aggregate value.
71             Finally, the squish snippet takes \$a representing the final aggregate
72             value so far and produces the final answer for the aggregator.
73              
74             Example(s):
75             __FORMAT_TEXT__
76             Track count and sum to produce average:
77             ii_agg(<<[0, 0]>>, <<[\$a->[0] + 1, \$a->[1] + {{ct}}]>>, <<\$a->[1] / \$a->[0]>>)
78              
79             for_field(qr/.../, )
80             __FORMAT_TEXT__
81             Takes a regex and a snippet of code. Creates an aggregator that creates
82             a map. Keys in the map correspond to fields chosen by matching the regex
83             against the fields from input records. Values in the map are produced by
84             aggregators which the snippet must act as a factory for (\$f is the
85             field).
86              
87             Example(s):
88             __FORMAT_TEXT__
89             To aggregate the sums of all the fields beginning with "t"
90             for_field(qr/^t/, <>)
91              
92             for_field(qr/.../, qr/.../, )
93             __FORMAT_TEXT__
94             Takes two regexes and a snippet of code. Creates an aggregator that
95             creates a map. Keys in the map correspond to pairs of fields chosen by
96             matching the regexes against the fields from input records. Values in
97             the map are produced by aggregators which the snippet must act as a
98             factory for (\$f1 is the first field, \$f2 is the second field).
99              
100             Example(s):
101             __FORMAT_TEXT__
102             To find the covariance of all x-named fields with all y-named fields:
103             for_field(qr/^x/, qr/^y/, <>)
104              
105             map_reduce_agg(, [, ])
106             map_reduce_aggregator(, [, ])
107             mr_agg(, [, ])
108             mr_aggregator(, [, ])
109             __FORMAT_TEXT__
110             Take a map snippet, a reduce snippet, and an optional squish snippet to
111             produce an ad-hoc aggregator based on map reduce. The map snippet takes
112             \$r representing a record and returns its mapped value. The reduce
113             snippet takes \$a and \$b representing two mapped values and combines
114             them. Finally, the squish snippet takes a mapped value \$a representing
115             all the records and produces the final answer for the aggregator.
116              
117             Example(s):
118             __FORMAT_TEXT__
119             Track count and sum to produce average:
120             mr_agg(<<[1, {{ct}}]>>, <<[\$a->[0] + \$b->[0], \$a->[1] + \$b->[1]]>>, <<\$a->[1] / \$a->[0]>>)
121              
122             rec()
123             record()
124             __FORMAT_TEXT__
125             A valuation that just returns the entire record.
126             __FORMAT_TEXT__
127              
128             snip(snip)
129             __FORMAT_TEXT__
130             Takes a snippet and returns both the snippet and the snippet as a
131             valuation. Used to distinguished snippets from scalars in cases where it
132             matters, e.g. min('{{x}}') interprets it is a keyspec when it was meant
133             to be a snippet (and then a valuation), min(snip('{{x}}')) does what is
134             intended. This is used internally by <<...>> and in fact <<...>> just
135             translates to snip('...').
136             __FORMAT_TEXT__
137              
138             subset_agg(, )
139             subset_aggregator(, )
140             __FORMAT_TEXT__
141             Takes a snippate to act as a record predicate and an aggregator and
142             produces an aggregator that acts as the provided aggregator as run on the
143             filtered view.
144              
145             Example(s):
146             __FORMAT_TEXT__
147             An aggregator that counts the number of records with a time not above 6 seconds:
148             subset_agg(<<{{time_ms}} <= 6000>>, ct())
149              
150             type_agg(obj)
151             type_scalar(obj)
152             type_val(obj)
153             __FORMAT_TEXT__
154             Force the object into a specific type. Can be used to force certain
155             upconversions (or avoid them).
156             __FORMAT_TEXT__
157              
158             valuation(sub { ... })
159             val(sub { ... })
160             __FORMAT_TEXT__
161             Takes a subref, creates a valuation that represents it. The subref will
162             get the record as its first and only argument.
163             __FORMAT_TEXT__
164              
165             Example(s):
166             To get the square of the "x" field:
167             val(sub{ \$[0]->{x} ** 2 })
168              
169             xform(, )
170             __FORMAT_TEXT__
171             Takes an aggregator and a snippet and produces an aggregator the
172             represents invoking the snippet on the aggregator's result.
173             __FORMAT_TEXT__
174              
175             Example(s):
176             To take the difference between the first and second time fields of the record collection:
177             xform(recs(), <<{{1/time}} - {{0/time}}>>)
178             HELP
179             }
180              
181             1;