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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58506c06a6a555805358ad1545cf71769fc2f3cb
4
- data.tar.gz: 0c7d1b25af500789ebb0f91c95bd407349f30eac
3
+ metadata.gz: 2e80806b87220aafb51408e7801435ebe84c64f6
4
+ data.tar.gz: 29903ea55cce4b8da0523630f8b551168b274eed
5
5
  SHA512:
6
- metadata.gz: f8da3f12f7657164c0099b5eab8f731086b220b76a2d0b87b9abde68aa1e01a0ff965f7049ff0ae128632160f299e8447a016591f49b047ba426081a41c06883
7
- data.tar.gz: 71486cc4c617bfc55ebc6c7f3622abee44ed380a381696007ba3f1143e410ed97519bf78016f5d1793d329c61dd4b66258f1134a748535cd77ffdda1d085c9c5
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
- piece.pass_on(msg, take_function(how_many -1))
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
@@ -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
@@ -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)
@@ -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 initialize(destination, what_to_do)
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
@@ -3,5 +3,8 @@ module Aqueductron
3
3
  def result?
4
4
  true
5
5
  end
6
+ def inspect
7
+ "Result:\n" + draw.join("\n")
8
+ end
6
9
  end
7
10
  end
@@ -14,5 +14,13 @@ module Aqueductron
14
14
  def value
15
15
  @value
16
16
  end
17
+
18
+ def to_hash
19
+ @value
20
+ end
21
+
22
+ def draw
23
+ [ "=> #{@value}"]
24
+ end
17
25
  end
18
26
  end
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.1
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-04 00:00:00.000000000 Z
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