dataflow 0.1.1 → 0.2.0

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