aqueductron 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|