aqueductron 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/aqueductron/array_end_piece.rb +23 -0
- data/lib/aqueductron/buildering.rb +7 -1
- data/lib/aqueductron/compound_result.rb +9 -0
- data/lib/aqueductron/counting_end_piece.rb +7 -0
- data/lib/aqueductron/drawing.rb +52 -0
- data/lib/aqueductron/end_piece.rb +5 -0
- data/lib/aqueductron/inlet.rb +3 -3
- data/lib/aqueductron/joint_piece.rb +7 -0
- data/lib/aqueductron/last_end_piece.rb +5 -0
- data/lib/aqueductron/monoid.rb +3 -2
- data/lib/aqueductron/partition.rb +6 -0
- data/lib/aqueductron/piece.rb +11 -4
- data/lib/aqueductron/piece_common.rb +9 -0
- data/lib/aqueductron/result.rb +3 -0
- data/lib/aqueductron/simple_result.rb +8 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e80806b87220aafb51408e7801435ebe84c64f6
|
4
|
+
data.tar.gz: 29903ea55cce4b8da0523630f8b551168b274eed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81107728aec0816bdcbcff836ecdf70018c0f1efda65784ff8744695a877b32b8ca2ecccba0daf9a31114161705b119b6ca4259d02c7836203485edb7b3830c6
|
7
|
+
data.tar.gz: 39e64b9ad5d886ce4ba598131427f15cecbea75d3b4306c6be9c9b817ffd01204d5143c607cb4c75692aaff261817d6fb04dc751953fd419af1671062e31279d
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'piece_common'
|
2
|
+
require_relative 'drawing'
|
3
|
+
|
4
|
+
module Aqueductron
|
5
|
+
class ArrayEndPiece
|
6
|
+
include PieceCommon
|
7
|
+
def initialize(so_far = [])
|
8
|
+
@so_far = so_far
|
9
|
+
end
|
10
|
+
def eof
|
11
|
+
SimpleResult.new(@so_far)
|
12
|
+
end
|
13
|
+
def receive msg
|
14
|
+
ArrayEndPiece.new(@so_far + [msg])
|
15
|
+
end
|
16
|
+
|
17
|
+
def draw
|
18
|
+
desc = @so_far.empty? ? "[]" : "[] (#{@so_far})"
|
19
|
+
Drawing.draw_end_piece(desc)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -5,6 +5,7 @@ require_relative 'inlet'
|
|
5
5
|
require_relative 'joint_piece'
|
6
6
|
require_relative 'piece'
|
7
7
|
require_relative 'partition'
|
8
|
+
require_relative 'array_end_piece'
|
8
9
|
|
9
10
|
module Aqueductron
|
10
11
|
module Buildering
|
@@ -16,6 +17,10 @@ module Aqueductron
|
|
16
17
|
answer_int(CountingEndPiece.new)
|
17
18
|
end
|
18
19
|
|
20
|
+
def array
|
21
|
+
answer_int(ArrayEndPiece.new)
|
22
|
+
end
|
23
|
+
|
19
24
|
def take(how_many)
|
20
25
|
attach(take_function(how_many))
|
21
26
|
end
|
@@ -54,7 +59,8 @@ module Aqueductron
|
|
54
59
|
if (how_many == 0) then # this is a little inefficient. One extra piece of info will be read
|
55
60
|
piece.send_eof
|
56
61
|
else
|
57
|
-
|
62
|
+
how_many_more = how_many - 1
|
63
|
+
piece.pass_on(msg, take_function(how_many_more), "taking #{how_many_more}")
|
58
64
|
end
|
59
65
|
end
|
60
66
|
end
|
@@ -15,5 +15,14 @@ module Aqueductron
|
|
15
15
|
puts "Nothing found at #{head}" unless @contents[head]
|
16
16
|
@contents[head].value(*tail)
|
17
17
|
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
@contents.map_values {|a| a.to_hash}
|
21
|
+
end
|
22
|
+
|
23
|
+
def draw
|
24
|
+
paths = Drawing.draw_multiple_paths(@contents)
|
25
|
+
Drawing.horizontal_concat(Drawing.joint_prefix, paths)
|
26
|
+
end
|
18
27
|
end
|
19
28
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'piece_common'
|
2
|
+
require_relative 'drawing'
|
2
3
|
|
3
4
|
module Aqueductron
|
4
5
|
class CountingEndPiece
|
@@ -12,5 +13,11 @@ module Aqueductron
|
|
12
13
|
def receive msg
|
13
14
|
CountingEndPiece.new(@so_far + 1)
|
14
15
|
end
|
16
|
+
|
17
|
+
def draw
|
18
|
+
desc = (@so_far > 0) ? "# (#{@so_far})" : "#"
|
19
|
+
Drawing.draw_end_piece(desc)
|
20
|
+
end
|
21
|
+
|
15
22
|
end
|
16
23
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Aqueductron
|
2
|
+
module Drawing
|
3
|
+
def self.draw_mid_piece(description)
|
4
|
+
dashes = "-" * description.length
|
5
|
+
[dashes, description, dashes]
|
6
|
+
end
|
7
|
+
def self.draw_end_piece(symbol)
|
8
|
+
["\\", " #{symbol}", "/"]
|
9
|
+
end
|
10
|
+
def self.joint_prefix
|
11
|
+
[" / ","< ", ' \\ ']
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.draw_multiple_paths(paths)
|
15
|
+
ducts = paths.keys.map{ |k| Drawing.horizontal_concat(Drawing.draw_mid_piece(" #{k.to_s} "), paths[k].draw) }.flatten(1)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.horizontal_concat(first, second)
|
19
|
+
# I <3 Ruby. this kind of recursive ref doesn't work in Scala
|
20
|
+
identity = ->(piece,msg) { piece.pass_on(msg, identity)}
|
21
|
+
concat_one_of_these= ->(array) {
|
22
|
+
->(piece,msg) {
|
23
|
+
(head, *tail) = array
|
24
|
+
if (tail.empty?)
|
25
|
+
piece.pass_on(msg + head, identity)
|
26
|
+
else
|
27
|
+
piece.pass_on(msg + head, concat_one_of_these.call(tail))
|
28
|
+
end
|
29
|
+
}
|
30
|
+
}
|
31
|
+
centeredSecond = centered_on(first.length, second)
|
32
|
+
centered_first = centered_on(second.length, first, padding(first), padding(first))
|
33
|
+
duct = Duct.new.custom(concat_one_of_these.call(centeredSecond)).array()
|
34
|
+
duct.flow(centered_first).value
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def self.centered_on(length, array, paddingBefore = "", paddingAfter = "")
|
39
|
+
if (length <= array.length)
|
40
|
+
array
|
41
|
+
else
|
42
|
+
top_spacing = (length - array.length) / 2
|
43
|
+
bottom_spacing = ((length - array.length) / 2.0).ceil
|
44
|
+
([paddingBefore] * top_spacing) + array + ([paddingAfter] * bottom_spacing)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.padding(array)
|
49
|
+
" " * array.first.length
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'piece_common'
|
2
2
|
require_relative 'simple_result'
|
3
|
+
require_relative 'drawing'
|
3
4
|
|
4
5
|
module Aqueductron
|
5
6
|
class EndPiece
|
@@ -16,5 +17,9 @@ module Aqueductron
|
|
16
17
|
def receive msg
|
17
18
|
EndPiece.new(@monoid, @monoid.append(@so_far, msg))
|
18
19
|
end
|
20
|
+
|
21
|
+
def draw
|
22
|
+
Drawing.draw_end_piece(@monoid.symbol)
|
23
|
+
end
|
19
24
|
end
|
20
25
|
end
|
data/lib/aqueductron/inlet.rb
CHANGED
@@ -9,16 +9,16 @@ module Aqueductron
|
|
9
9
|
flow_internal(source.each)
|
10
10
|
end
|
11
11
|
|
12
|
-
def flow_internal(source)
|
12
|
+
def flow_internal(source, send_eof = true)
|
13
13
|
result = begin
|
14
14
|
response = @next_piece.receive(source.next)
|
15
15
|
if (response.result?) then
|
16
16
|
response
|
17
17
|
else #it's another piece
|
18
|
-
Inlet.new(response, @done_or_not).flow_internal(source)
|
18
|
+
Inlet.new(response, @done_or_not).flow_internal(source, send_eof)
|
19
19
|
end
|
20
20
|
rescue StopIteration
|
21
|
-
if (@done_or_not == :done) then
|
21
|
+
if (@done_or_not == :done && send_eof) then
|
22
22
|
@next_piece.eof
|
23
23
|
else
|
24
24
|
@next_piece
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'compound_result'
|
2
2
|
require_relative 'piece_common'
|
3
|
+
require_relative 'drawing'
|
3
4
|
|
4
5
|
module Aqueductron
|
5
6
|
class JointPiece
|
@@ -24,6 +25,12 @@ module Aqueductron
|
|
24
25
|
construct_compound_result(new_map)
|
25
26
|
end
|
26
27
|
|
28
|
+
|
29
|
+
def draw
|
30
|
+
prefix = Drawing.joint_prefix
|
31
|
+
ducts = Drawing.draw_multiple_paths(@paths)
|
32
|
+
Drawing.horizontal_concat(prefix, ducts)
|
33
|
+
end
|
27
34
|
private
|
28
35
|
def construct_compound_result(paths)
|
29
36
|
CompoundResult.new(paths)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'piece_common'
|
2
|
+
require_relative 'drawing'
|
2
3
|
|
3
4
|
module Aqueductron
|
4
5
|
class LastEndPiece
|
@@ -12,5 +13,9 @@ module Aqueductron
|
|
12
13
|
def receive msg
|
13
14
|
LastEndPiece.new(msg)
|
14
15
|
end
|
16
|
+
def draw
|
17
|
+
desc = (@most_recent == :no_data)? "last" : "last (#{@most_recent})"
|
18
|
+
Drawing.draw_end_piece(desc)
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
data/lib/aqueductron/monoid.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Aqueductron
|
2
2
|
class Monoid
|
3
|
-
attr_reader :zero
|
4
|
-
def initialize(zero, add_lambda)
|
3
|
+
attr_reader :zero, :symbol
|
4
|
+
def initialize(zero, add_lambda, symbol = "+")
|
5
5
|
@zero = zero
|
6
6
|
@append = add_lambda
|
7
|
+
@symbol = symbol
|
7
8
|
end
|
8
9
|
def append(a,b)
|
9
10
|
@append.call(a,b)
|
@@ -35,6 +35,12 @@ module Aqueductron
|
|
35
35
|
construct_compound_result(new_map)
|
36
36
|
end
|
37
37
|
|
38
|
+
def draw
|
39
|
+
ducts = Drawing.draw_multiple_paths(@paths)
|
40
|
+
paths = (ducts + ["+?"]).flatten
|
41
|
+
Drawing.horizontal_concat(Drawing.joint_prefix, paths)
|
42
|
+
end
|
43
|
+
|
38
44
|
private
|
39
45
|
def construct_compound_result(paths)
|
40
46
|
CompoundResult.new(paths)
|
data/lib/aqueductron/piece.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
require_relative 'piece_common'
|
2
|
+
require_relative 'drawing'
|
2
3
|
|
3
4
|
module Aqueductron
|
4
5
|
class Piece
|
5
6
|
attr_reader :destination
|
6
7
|
include PieceCommon
|
7
8
|
|
8
|
-
def
|
9
|
+
def draw
|
10
|
+
desc = " " + @description + " "
|
11
|
+
Drawing.horizontal_concat(Drawing.draw_mid_piece(desc),@destination.draw)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(destination, what_to_do, description = "~")
|
9
15
|
@destination = destination
|
10
16
|
@what_to_do = what_to_do
|
17
|
+
@description = description
|
11
18
|
end
|
12
19
|
|
13
20
|
def receive(msg)
|
@@ -18,12 +25,12 @@ module Aqueductron
|
|
18
25
|
send_eof
|
19
26
|
end
|
20
27
|
|
21
|
-
def pass_on(msg, what_to_do_next)
|
28
|
+
def pass_on(msg, what_to_do_next, description = "~")
|
22
29
|
next_destination = @destination.receive(msg)
|
23
30
|
if (next_destination.result?) then
|
24
|
-
next_destination
|
31
|
+
next_destination # not a destination at all; result
|
25
32
|
else
|
26
|
-
Piece.new(next_destination, what_to_do_next)
|
33
|
+
Piece.new(next_destination, what_to_do_next, description)
|
27
34
|
end
|
28
35
|
end
|
29
36
|
def send_eof
|
@@ -3,8 +3,17 @@ module Aqueductron
|
|
3
3
|
def flow(source)
|
4
4
|
Inlet.new(self).flow_internal(source.each)
|
5
5
|
end
|
6
|
+
def keep_flowing(source)
|
7
|
+
Inlet.new(self).flow_internal(source.each, false)
|
8
|
+
end
|
9
|
+
def drip(one_thing)
|
10
|
+
keep_flowing([one_thing])
|
11
|
+
end
|
6
12
|
def result?
|
7
13
|
false
|
8
14
|
end
|
15
|
+
def inspect
|
16
|
+
"Duct:\n" + draw.join("\n")
|
17
|
+
end
|
9
18
|
end
|
10
19
|
end
|
data/lib/aqueductron/result.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aqueductron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jessica Kerr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Aqueductron lets you create a path for data, then flow data through it,
|
14
14
|
then find the results at the end. It encourages a functional style, avoiding mutable
|
@@ -18,9 +18,11 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- lib/aqueductron/array_end_piece.rb
|
21
22
|
- lib/aqueductron/buildering.rb
|
22
23
|
- lib/aqueductron/compound_result.rb
|
23
24
|
- lib/aqueductron/counting_end_piece.rb
|
25
|
+
- lib/aqueductron/drawing.rb
|
24
26
|
- lib/aqueductron/duct.rb
|
25
27
|
- lib/aqueductron/end_piece.rb
|
26
28
|
- lib/aqueductron/inlet.rb
|