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 +25 -0
- data/README.textile +19 -0
- data/Rakefile +1 -1
- data/dataflow.rb +10 -8
- data/{lib → dataflow}/actor.rb +0 -0
- data/dataflow/equality.rb +28 -0
- data/{lib → dataflow}/port.rb +0 -0
- data/spec/actor_spec.rb +0 -1
- data/spec/by_need_spec.rb +50 -7
- data/spec/equality_spec.rb +40 -0
- data/spec/inspect_spec.rb +19 -0
- data/spec/spec_helper.rb +4 -1
- metadata +18 -15
- data/History.txt +0 -12
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
|
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.
|
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
|
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
|
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
|
-
|
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
|
-
|
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__)}/
|
90
|
-
require "#{File.dirname(__FILE__)}/
|
91
|
+
require "#{File.dirname(__FILE__)}/dataflow/port"
|
92
|
+
require "#{File.dirname(__FILE__)}/dataflow/actor"
|
data/{lib → dataflow}/actor.rb
RENAMED
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
|
data/{lib → dataflow}/port.rb
RENAMED
File without changes
|
data/spec/actor_spec.rb
CHANGED
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
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
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.
|
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-
|
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
|
-
-
|
26
|
+
- HISTORY
|
27
27
|
- Rakefile
|
28
28
|
- README.textile
|
29
29
|
- dataflow.rb
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
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/
|
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/
|
70
|
+
- spec/actor_spec.rb
|
70
71
|
- spec/by_need_spec.rb
|
71
|
-
- spec/
|
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/
|
75
|
-
- spec/actor_spec.rb
|
78
|
+
- spec/spec_helper.rb
|