dataflow 0.1.1 → 0.2.0

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.
data/HISTORY ADDED
@@ -0,0 +1,25 @@
1
+ == 0.2.0 / 2009-07-09
2
+
3
+ * Major enhancements
4
+
5
+ * Made equality between objects and dataflow variables more transparent
6
+ (load equality changes with: require 'dataflow/equality')
7
+
8
+ * Minor enhancements
9
+
10
+ * Made #inspect work with unbound variables to not crash deubggers/repls/etc
11
+
12
+ * Made relationship between lazy and dataflow behavior more strict
13
+
14
+ == 0.1.1 / 2009-06-13
15
+
16
+ * Minor enhancements
17
+
18
+ * Got the "require_path" set correctly so rubygems can be used =)
19
+
20
+
21
+ == 0.1.0 / 2009-06-13
22
+
23
+ * 1 major enhancement
24
+
25
+ * Birthday!
data/README.textile CHANGED
@@ -34,6 +34,15 @@ side-effects. Use regular Ruby threading to create threads, use
34
34
  "local" or "declare" to create new variables, and use "unify" to bind
35
35
  variables.
36
36
 
37
+ h1. Install
38
+
39
+ To install the latest release as a gem:
40
+ <pre>sudo gem install dataflow</pre>
41
+
42
+ h1. IRC
43
+
44
+ <pre>#dataflow-gem @ freenode.net</pre>
45
+
37
46
  h1. Examples
38
47
 
39
48
  <pre>
@@ -160,6 +169,16 @@ Ping.join
160
169
  Pong.join
161
170
  </pre>
162
171
 
172
+ h1. Equality
173
+
174
+ Most Ruby implmentations will not use method calls for equality
175
+ operations in base types/classes. This means equality between dataflow
176
+ variables and those base types will not behave as expected. Require
177
+ the following to get equality on base types that uses method calls,
178
+ while still passing rubyspec:
179
+
180
+ <pre>require "dataflow/equality"</pre>
181
+
163
182
  h1. References
164
183
 
165
184
  The basis of dataflow variables around a language is not common among
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ spec = Gem::Specification.new do |s|
20
20
  s.homepage = "http://github.com/larrytheliquid/dataflow"
21
21
  s.summary = "Dataflow concurrency for Ruby (inspired by the Oz language)"
22
22
  s.description = s.summary
23
- s.files = %w[LICENSE History.txt Rakefile README.textile dataflow.rb] + Dir["lib/**/*"] + Dir["examples/**/*"]
23
+ s.files = %w[LICENSE HISTORY Rakefile README.textile dataflow.rb] + Dir["dataflow/**/*"] + Dir["examples/**/*"]
24
24
  s.require_path = '.'
25
25
  s.test_files = Dir["spec/**/*"]
26
26
  end
data/dataflow.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'monitor'
2
2
 
3
3
  module Dataflow
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
 
6
6
  def self.included(cls)
7
7
  class << cls
@@ -42,22 +42,23 @@ module Dataflow
42
42
  # initialized instance variables in get/set methods for memory and
43
43
  # performance reasons
44
44
  class Variable
45
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
45
+ instance_methods.each { |m| undef_method m }
46
46
  LOCK = Monitor.new
47
47
  def initialize(&block) @__trigger__ = block if block_given? end
48
48
 
49
49
  # Lazy-load conditions to be nice on memory usage
50
50
  def __binding_condition__() @__binding_condition__ ||= LOCK.new_cond end
51
-
51
+
52
52
  def __unify__(value)
53
53
  LOCK.synchronize do
54
+ __activate_trigger__ if @__trigger__
54
55
  if @__bound__
55
- raise UnificationError if @__value__ != value
56
+ raise UnificationError if self != value
56
57
  else
57
58
  @__value__ = value
58
59
  @__bound__ = true
59
60
  __binding_condition__.broadcast # wakeup all method callers
60
- remove_instance_variable :@__binding_condition__ # GC
61
+ @__binding_condition__ = nil # GC
61
62
  end
62
63
  end
63
64
  @__value__
@@ -66,12 +67,13 @@ module Dataflow
66
67
  def __activate_trigger__
67
68
  @__value__ = @__trigger__.call
68
69
  @__bound__ = true
69
- remove_instance_variable :@__trigger__ # GC
70
+ @__trigger__ = nil # GC
70
71
  end
71
72
 
72
73
  def method_missing(name, *args, &block)
73
74
  LOCK.synchronize do
74
75
  unless @__bound__
76
+ return '#<Dataflow::Variable unbound>' if name == :inspect
75
77
  if @__trigger__
76
78
  __activate_trigger__
77
79
  else
@@ -86,5 +88,5 @@ module Dataflow
86
88
  UnificationError = Class.new StandardError
87
89
  end
88
90
 
89
- require "#{File.dirname(__FILE__)}/lib/port"
90
- require "#{File.dirname(__FILE__)}/lib/actor"
91
+ require "#{File.dirname(__FILE__)}/dataflow/port"
92
+ require "#{File.dirname(__FILE__)}/dataflow/actor"
File without changes
@@ -0,0 +1,28 @@
1
+ # The purpose of this file is to make equality use method calls in as
2
+ # many Ruby implementations as possible. If method calls are used,
3
+ # then equality operations using dataflow variaables becomes seemless
4
+ # I realize overriding core classes is a pretty nasty hack, but if you
5
+ # have a better idea that also passes the equality_specs then I'm all
6
+ # ears. Please run the rubyspec before committing changes to this file.
7
+
8
+ class Object
9
+ def ==(other)
10
+ __id__ == other.__id__
11
+ end
12
+ end
13
+
14
+ class Symbol
15
+ def ==(other)
16
+ __id__ == other.__id__
17
+ end
18
+ end
19
+
20
+ class Regexp
21
+ def ==(other)
22
+ other.is_a?(Regexp) &&
23
+ casefold? == other.casefold? &&
24
+ kcode == other.kcode &&
25
+ options == other.options &&
26
+ source == other.source
27
+ end
28
+ end
File without changes
data/spec/actor_spec.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "#{File.dirname(__FILE__)}/spec_helper"
2
- Thread.abort_on_exception = true
3
2
 
4
3
  describe 'Syncronously sending to an Actor' do
5
4
  it 'passes in each message received and preserves order' do
data/spec/by_need_spec.rb CHANGED
@@ -1,12 +1,55 @@
1
1
  require "#{File.dirname(__FILE__)}/spec_helper"
2
2
 
3
- describe 'A by_need trigger' do
4
- it 'creates a need when a method is called on it' do
5
- local do |x, y, z|
6
- Thread.new { unify y, by_need { 4 } }
7
- Thread.new { unify z, x + y }
8
- Thread.new { unify x, by_need { 3 } }
9
- z.should == 7
3
+ describe 'A by_need expression' do
4
+ describe 'when a method is called on it' do
5
+ it 'binds its variable' do
6
+ local do |x, y, z|
7
+ Thread.new { unify y, by_need { 4 } }
8
+ Thread.new { unify z, x + y }
9
+ Thread.new { unify x, by_need { 3 } }
10
+ z.should == 7
11
+ end
12
+ end
13
+ end
14
+
15
+ describe 'when a bound variable is unified to it' do
16
+ it 'passes unififcation for equal values' do
17
+ local do |x|
18
+ unify x, by_need { 1 }
19
+ unify x, 1
20
+ x.should == 1
21
+
22
+ y = by_need { 1 }
23
+ unify y, 1
24
+ y.should == 1
25
+ end
26
+ end
27
+
28
+ it 'fails unififcation for unequal values' do
29
+ local do |x|
30
+ unify x, by_need { 1 }
31
+ lambda { unify x, 2 }.should raise_error(Dataflow::UnificationError)
32
+
33
+ y = by_need { 1 }
34
+ lambda { unify y, 2 }.should raise_error(Dataflow::UnificationError)
35
+ end
36
+ end
37
+
38
+ describe 'when it is unified to a bound variable' do
39
+ it 'passes unififcation for equal values' do
40
+ local do |x|
41
+ unify x, 1
42
+ unify x, by_need { 1 }
43
+ x.should == 1
44
+ end
45
+ end
46
+
47
+ it 'fails unification for unequal values' do
48
+ local do |x|
49
+ unify x, 1
50
+ lambda { unify x, by_need { 2 } }.should raise_error(Dataflow::UnificationError)
51
+ end
52
+ end
10
53
  end
11
54
  end
12
55
  end
@@ -0,0 +1,40 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe 'Unifying a bound value' do
4
+ [nil, true, false,
5
+ :sym, "str", /regex/,
6
+ 3, 2.0,
7
+ Object.new, Class.new.new,
8
+ [], {}].each do |type|
9
+ describe "for #{type.class} instances" do
10
+ it 'passes unification for an object of equal value' do
11
+ local do |var, var2|
12
+ unify var, type
13
+ var.should == type
14
+ type.should == var
15
+ lambda {unify var, type}.should_not raise_error
16
+
17
+ unify var2, type
18
+ var.should == var2
19
+ var2.should == var
20
+ lambda {unify var, var2}.should_not raise_error
21
+ end
22
+ end
23
+
24
+ it 'fails unification for an object of inequal value' do
25
+ different = Object.new
26
+ local do |var, var2|
27
+ unify var, type
28
+ var.should_not == different
29
+ different.should_not == var
30
+ lambda {unify var, different}.should raise_error(Dataflow::UnificationError)
31
+
32
+ unify var2, different
33
+ var.should_not == var2
34
+ var2.should_not == var
35
+ lambda {unify var, different}.should raise_error(Dataflow::UnificationError)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe "An unbound variable" do
4
+ it "should be inspectable for debugging purposes" do
5
+ local do |unbound|
6
+ unbound.inspect.should == "#<Dataflow::Variable unbound>"
7
+ end
8
+ end
9
+ end
10
+
11
+ describe "An bound variable" do
12
+ it "should proxy inspect" do
13
+ local do |bound|
14
+ bound.inspect
15
+ unify bound, "str"
16
+ bound.should == "str"
17
+ end
18
+ end
19
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- require 'dataflow'
3
+ require "#{File.dirname(__FILE__)}/../dataflow"
4
+ require "#{File.dirname(__FILE__)}/../dataflow/equality"
5
+
6
+ Thread.abort_on_exception = true
4
7
 
5
8
  Spec::Runner.configure do |config|
6
9
  config.include Dataflow
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dataflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Larry Diehl
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-13 00:00:00 -07:00
12
+ date: 2009-07-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -23,22 +23,23 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - LICENSE
26
- - History.txt
26
+ - HISTORY
27
27
  - Rakefile
28
28
  - README.textile
29
29
  - dataflow.rb
30
- - lib/actor.rb
31
- - lib/port.rb
32
- - examples/local_variables.rb
30
+ - dataflow/actor.rb
31
+ - dataflow/equality.rb
32
+ - dataflow/port.rb
33
+ - examples/data_driven.rb
33
34
  - examples/dataflow_http_gets.rb
35
+ - examples/future_http_gets.rb
34
36
  - examples/instance_variables.rb
35
- - examples/data_driven.rb
36
- - examples/ring.rb
37
- - examples/port_send.rb
38
37
  - examples/laziness.rb
39
- - examples/port_http_gets.rb
40
- - examples/future_http_gets.rb
38
+ - examples/local_variables.rb
41
39
  - examples/messages.rb
40
+ - examples/port_http_gets.rb
41
+ - examples/port_send.rb
42
+ - examples/ring.rb
42
43
  has_rdoc: false
43
44
  homepage: http://github.com/larrytheliquid/dataflow
44
45
  post_install_message:
@@ -66,10 +67,12 @@ signing_key:
66
67
  specification_version: 2
67
68
  summary: Dataflow concurrency for Ruby (inspired by the Oz language)
68
69
  test_files:
69
- - spec/need_later_spec.rb
70
+ - spec/actor_spec.rb
70
71
  - spec/by_need_spec.rb
71
- - spec/spec_helper.rb
72
+ - spec/dataflow_spec.rb
73
+ - spec/equality_spec.rb
74
+ - spec/inspect_spec.rb
75
+ - spec/need_later_spec.rb
72
76
  - spec/port_spec.rb
73
77
  - spec/spec.opts
74
- - spec/dataflow_spec.rb
75
- - spec/actor_spec.rb
78
+ - spec/spec_helper.rb
data/History.txt DELETED
@@ -1,12 +0,0 @@
1
- == 0.1.1 / 2009-06-13
2
-
3
- * Minor enhancements
4
-
5
- * Got the "require_path" set correctly so rubygems can be used =)
6
-
7
-
8
- == 0.1.0 / 2009-06-13
9
-
10
- * 1 major enhancement
11
-
12
- * Birthday!