engineyard-serverside 2.0.4 → 2.0.5.pre
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/lib/engineyard-serverside.rb +2 -1
- data/lib/engineyard-serverside/about.rb +37 -0
- data/lib/engineyard-serverside/cli.rb +2 -49
- data/lib/engineyard-serverside/configuration.rb +1 -0
- data/lib/engineyard-serverside/deploy.rb +5 -8
- data/lib/engineyard-serverside/propagator.rb +75 -0
- data/lib/engineyard-serverside/server.rb +3 -2
- data/lib/engineyard-serverside/servers.rb +28 -14
- data/lib/engineyard-serverside/shell.rb +6 -6
- data/lib/engineyard-serverside/shell/command_result.rb +1 -1
- data/lib/engineyard-serverside/strategies/git.rb +9 -4
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/propagator_spec.rb +95 -0
- data/spec/spec_helper.rb +1 -1
- metadata +47 -68
- data/lib/engineyard-serverside/future.rb +0 -35
- data/lib/engineyard-serverside/futures/celluloid.rb +0 -15
- data/lib/engineyard-serverside/futures/dataflow.rb +0 -26
- data/lib/vendor/celluloid/lib/celluloid.rb +0 -261
- data/lib/vendor/celluloid/lib/celluloid/actor.rb +0 -242
- data/lib/vendor/celluloid/lib/celluloid/actor_pool.rb +0 -54
- data/lib/vendor/celluloid/lib/celluloid/actor_proxy.rb +0 -75
- data/lib/vendor/celluloid/lib/celluloid/application.rb +0 -78
- data/lib/vendor/celluloid/lib/celluloid/calls.rb +0 -93
- data/lib/vendor/celluloid/lib/celluloid/core_ext.rb +0 -14
- data/lib/vendor/celluloid/lib/celluloid/events.rb +0 -14
- data/lib/vendor/celluloid/lib/celluloid/fiber.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/fsm.rb +0 -141
- data/lib/vendor/celluloid/lib/celluloid/future.rb +0 -60
- data/lib/vendor/celluloid/lib/celluloid/links.rb +0 -61
- data/lib/vendor/celluloid/lib/celluloid/logger.rb +0 -32
- data/lib/vendor/celluloid/lib/celluloid/mailbox.rb +0 -124
- data/lib/vendor/celluloid/lib/celluloid/receivers.rb +0 -66
- data/lib/vendor/celluloid/lib/celluloid/registry.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/responses.rb +0 -26
- data/lib/vendor/celluloid/lib/celluloid/rspec.rb +0 -2
- data/lib/vendor/celluloid/lib/celluloid/signals.rb +0 -50
- data/lib/vendor/celluloid/lib/celluloid/supervisor.rb +0 -57
- data/lib/vendor/celluloid/lib/celluloid/task.rb +0 -73
- data/lib/vendor/celluloid/lib/celluloid/tcp_server.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/timers.rb +0 -109
- data/lib/vendor/celluloid/lib/celluloid/version.rb +0 -4
- data/lib/vendor/dataflow/HISTORY +0 -52
- data/lib/vendor/dataflow/LICENSE +0 -19
- data/lib/vendor/dataflow/README.textile +0 -290
- data/lib/vendor/dataflow/Rakefile +0 -36
- data/lib/vendor/dataflow/dataflow.rb +0 -124
- data/lib/vendor/dataflow/dataflow/actor.rb +0 -22
- data/lib/vendor/dataflow/dataflow/equality.rb +0 -44
- data/lib/vendor/dataflow/dataflow/future_queue.rb +0 -24
- data/lib/vendor/dataflow/dataflow/port.rb +0 -54
- data/lib/vendor/dataflow/examples/barrier.rb +0 -9
- data/lib/vendor/dataflow/examples/data_driven.rb +0 -17
- data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +0 -13
- data/lib/vendor/dataflow/examples/flow.rb +0 -20
- data/lib/vendor/dataflow/examples/future_http_gets.rb +0 -12
- data/lib/vendor/dataflow/examples/future_queue.rb +0 -11
- data/lib/vendor/dataflow/examples/instance_variables.rb +0 -15
- data/lib/vendor/dataflow/examples/laziness.rb +0 -9
- data/lib/vendor/dataflow/examples/local_variables.rb +0 -11
- data/lib/vendor/dataflow/examples/messages.rb +0 -26
- data/lib/vendor/dataflow/examples/port_http_gets.rb +0 -13
- data/lib/vendor/dataflow/examples/port_send.rb +0 -10
- data/lib/vendor/dataflow/examples/ring.rb +0 -21
- data/lib/vendor/dataflow/spec/actor_spec.rb +0 -28
- data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +0 -21
- data/lib/vendor/dataflow/spec/barrier_spec.rb +0 -25
- data/lib/vendor/dataflow/spec/by_need_spec.rb +0 -55
- data/lib/vendor/dataflow/spec/dataflow_spec.rb +0 -151
- data/lib/vendor/dataflow/spec/equality_spec.rb +0 -40
- data/lib/vendor/dataflow/spec/flow_spec.rb +0 -25
- data/lib/vendor/dataflow/spec/forker_spec.rb +0 -28
- data/lib/vendor/dataflow/spec/future_queue_spec.rb +0 -31
- data/lib/vendor/dataflow/spec/inspect_spec.rb +0 -19
- data/lib/vendor/dataflow/spec/need_later_spec.rb +0 -12
- data/lib/vendor/dataflow/spec/port_spec.rb +0 -26
- data/lib/vendor/dataflow/spec/spec.opts +0 -1
- data/lib/vendor/dataflow/spec/spec_helper.rb +0 -10
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
require "rubygems"
|
|
2
|
-
require "rake/gempackagetask"
|
|
3
|
-
require "rake/clean"
|
|
4
|
-
require "spec/rake/spectask"
|
|
5
|
-
require File.expand_path("./dataflow")
|
|
6
|
-
|
|
7
|
-
Spec::Rake::SpecTask.new do |t|
|
|
8
|
-
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
desc "Run the specs"
|
|
12
|
-
task :default => :spec
|
|
13
|
-
|
|
14
|
-
spec = Gem::Specification.new do |s|
|
|
15
|
-
s.name = "dataflow"
|
|
16
|
-
s.rubyforge_project = s.name
|
|
17
|
-
s.version = Dataflow::VERSION
|
|
18
|
-
s.author = "Larry Diehl"
|
|
19
|
-
s.email = "larrytheliquid" + "@" + "gmail.com"
|
|
20
|
-
s.homepage = "http://github.com/larrytheliquid/dataflow"
|
|
21
|
-
s.summary = "Dataflow concurrency for Ruby (inspired by the Oz language)"
|
|
22
|
-
s.description = s.summary
|
|
23
|
-
s.files = %w[LICENSE HISTORY Rakefile README.textile dataflow.rb] + Dir["dataflow/**/*"] + Dir["examples/**/*"]
|
|
24
|
-
s.require_path = '.'
|
|
25
|
-
s.test_files = Dir["spec/**/*"]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
Rake::GemPackageTask.new(spec) do |package|
|
|
29
|
-
package.gem_spec = spec
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
desc 'Install the package as a gem.'
|
|
33
|
-
task :install => [:clean, :package] do
|
|
34
|
-
gem = Dir['pkg/*.gem'].first
|
|
35
|
-
sh "sudo gem install --no-rdoc --no-ri --local #{gem}"
|
|
36
|
-
end
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
require 'monitor'
|
|
2
|
-
|
|
3
|
-
module Dataflow
|
|
4
|
-
VERSION = "0.3.1"
|
|
5
|
-
class << self
|
|
6
|
-
attr_accessor :forker
|
|
7
|
-
end
|
|
8
|
-
self.forker = Thread.method(:fork)
|
|
9
|
-
|
|
10
|
-
def self.included(cls)
|
|
11
|
-
class << cls
|
|
12
|
-
def declare(*readers)
|
|
13
|
-
readers.each do |name|
|
|
14
|
-
class_eval <<-RUBY
|
|
15
|
-
def #{name}
|
|
16
|
-
return @__dataflow_#{name}__ if defined? @__dataflow_#{name}__
|
|
17
|
-
Variable::LOCK.synchronize { @__dataflow_#{name}__ ||= Variable.new }
|
|
18
|
-
end
|
|
19
|
-
RUBY
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def local(&block)
|
|
26
|
-
return Variable.new unless block_given?
|
|
27
|
-
vars = Array.new(block.arity) { Variable.new }
|
|
28
|
-
block.call *vars
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def unify(variable, value)
|
|
32
|
-
variable.__unify__ value
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def by_need(&block)
|
|
36
|
-
Variable.new &block
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def barrier(*variables)
|
|
40
|
-
variables.each{|v| v.__wait__ }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def flow(output=nil, &block)
|
|
44
|
-
Dataflow.forker.call do
|
|
45
|
-
result = block.call
|
|
46
|
-
unify output, result if output
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def need_later(&block)
|
|
51
|
-
local do |future|
|
|
52
|
-
flow(future) { block.call }
|
|
53
|
-
future
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
extend self
|
|
58
|
-
|
|
59
|
-
# Note that this class uses instance variables directly rather than nicely
|
|
60
|
-
# initialized instance variables in get/set methods for memory and
|
|
61
|
-
# performance reasons
|
|
62
|
-
class Variable
|
|
63
|
-
# Briefly disable the warning we would get when undefining object_id.
|
|
64
|
-
# We actually rely on the ability to do that, so...
|
|
65
|
-
v = $VERBOSE; $VERBOSE = nil
|
|
66
|
-
instance_methods.each { |m| undef_method(m) unless m =~ /^__|instance_eval/ }
|
|
67
|
-
$VERBOSE = v # back to sanity
|
|
68
|
-
LOCK = Monitor.new
|
|
69
|
-
def initialize(&block) @__trigger__ = block if block_given? end
|
|
70
|
-
|
|
71
|
-
# Lazy-load conditions to be nice on memory usage
|
|
72
|
-
def __binding_condition__() @__binding_condition__ ||= LOCK.new_cond end
|
|
73
|
-
|
|
74
|
-
def __unify__(value)
|
|
75
|
-
LOCK.synchronize do
|
|
76
|
-
__activate_trigger__ if @__trigger__
|
|
77
|
-
if @__bound__
|
|
78
|
-
return @__value__.__unify__(value) if @__value__.__dataflow__? rescue nil
|
|
79
|
-
raise UnificationError, "#{@__value__.inspect} != #{value.inspect}" if self != value
|
|
80
|
-
else
|
|
81
|
-
@__value__ = value
|
|
82
|
-
@__bound__ = true
|
|
83
|
-
__binding_condition__.broadcast # wakeup all method callers
|
|
84
|
-
@__binding_condition__ = nil # GC
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
@__value__
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def __activate_trigger__
|
|
91
|
-
@__value__ = @__trigger__.call
|
|
92
|
-
@__bound__ = true
|
|
93
|
-
@__trigger__ = nil # GC
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def __wait__
|
|
97
|
-
LOCK.synchronize do
|
|
98
|
-
unless @__bound__
|
|
99
|
-
if @__trigger__
|
|
100
|
-
__activate_trigger__
|
|
101
|
-
else
|
|
102
|
-
__binding_condition__.wait
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end unless @__bound__
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def method_missing(name, *args, &block)
|
|
109
|
-
return "#<Dataflow::Variable:#{__id__} unbound>" if !@__bound__ && name == :inspect
|
|
110
|
-
__wait__
|
|
111
|
-
@__value__.__send__(name, *args, &block)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def __dataflow__?
|
|
115
|
-
true
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
UnificationError = Class.new StandardError
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
require "#{File.dirname(__FILE__)}/dataflow/port"
|
|
123
|
-
require "#{File.dirname(__FILE__)}/dataflow/actor"
|
|
124
|
-
require "#{File.dirname(__FILE__)}/dataflow/future_queue"
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Dataflow
|
|
2
|
-
class Actor < Thread
|
|
3
|
-
def initialize(&block)
|
|
4
|
-
@stream = Variable.new
|
|
5
|
-
@port = Port.new(@stream)
|
|
6
|
-
# Run this block in a new thread
|
|
7
|
-
super { instance_eval &block }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def send message
|
|
11
|
-
@port.send message
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def receive
|
|
17
|
-
result = @stream.head
|
|
18
|
-
@stream = @stream.tail
|
|
19
|
-
result
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
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
|
-
alias original_equality ==
|
|
10
|
-
|
|
11
|
-
def ==(other)
|
|
12
|
-
object_id == other.object_id
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class Symbol
|
|
17
|
-
alias original_equality ==
|
|
18
|
-
|
|
19
|
-
def ==(other)
|
|
20
|
-
object_id == other.object_id
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
class Regexp
|
|
25
|
-
alias original_equality ==
|
|
26
|
-
|
|
27
|
-
if /lol/.respond_to?(:encoding)
|
|
28
|
-
def ==(other)
|
|
29
|
-
other.is_a?(Regexp) &&
|
|
30
|
-
casefold? == other.casefold? &&
|
|
31
|
-
encoding == other.encoding &&
|
|
32
|
-
options == other.options &&
|
|
33
|
-
source == other.source
|
|
34
|
-
end
|
|
35
|
-
else
|
|
36
|
-
def ==(other)
|
|
37
|
-
other.is_a?(Regexp) &&
|
|
38
|
-
casefold? == other.casefold? &&
|
|
39
|
-
kcode == other.kcode &&
|
|
40
|
-
options == other.options &&
|
|
41
|
-
source == other.source
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
module Dataflow
|
|
2
|
-
class FutureQueue
|
|
3
|
-
include Dataflow
|
|
4
|
-
declare :push_port, :pop_port
|
|
5
|
-
|
|
6
|
-
def initialize
|
|
7
|
-
local do |pushed, popped|
|
|
8
|
-
unify push_port, Dataflow::Port.new(pushed)
|
|
9
|
-
unify pop_port, Dataflow::Port.new(popped)
|
|
10
|
-
|
|
11
|
-
Thread.new {
|
|
12
|
-
loop do
|
|
13
|
-
barrier pushed.head, popped.head
|
|
14
|
-
unify popped.head, pushed.head
|
|
15
|
-
pushed, popped = pushed.tail, popped.tail
|
|
16
|
-
end
|
|
17
|
-
}
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def push(x) push_port.send x end
|
|
22
|
-
def pop(x) pop_port.send x end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
require 'thread'
|
|
2
|
-
|
|
3
|
-
module Dataflow
|
|
4
|
-
class Port
|
|
5
|
-
include Dataflow
|
|
6
|
-
LOCK = Mutex.new
|
|
7
|
-
|
|
8
|
-
class Stream
|
|
9
|
-
include Dataflow
|
|
10
|
-
declare :head, :tail
|
|
11
|
-
|
|
12
|
-
# Defining each allows us to use the enumerable mixin
|
|
13
|
-
# None of the list can be garbage collected less the head is
|
|
14
|
-
# garbage collected, so it will grow indefinitely even though
|
|
15
|
-
# the function isn't recursive.
|
|
16
|
-
include Enumerable
|
|
17
|
-
def each
|
|
18
|
-
s = self
|
|
19
|
-
loop do
|
|
20
|
-
yield s.head
|
|
21
|
-
s = s.tail
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Backported Enumerable#take for any 1.8.6 compatible Ruby
|
|
26
|
-
unless method_defined?(:take)
|
|
27
|
-
def take(num)
|
|
28
|
-
result = []
|
|
29
|
-
each_with_index do |x, i|
|
|
30
|
-
return result if num == i
|
|
31
|
-
result << x
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Create a stream object, bind it to the input variable
|
|
38
|
-
# Instance variables are necessary because @end is state
|
|
39
|
-
def initialize(x)
|
|
40
|
-
@end = Stream.new
|
|
41
|
-
unify x, @end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# This needs to be synchronized because it uses @end as state
|
|
45
|
-
def send value
|
|
46
|
-
LOCK.synchronize do
|
|
47
|
-
unify @end.head, value
|
|
48
|
-
unify @end.tail, Stream.new
|
|
49
|
-
@end = @end.tail
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
include Dataflow
|
|
3
|
-
|
|
4
|
-
local do |stream, doubles, triples, squares|
|
|
5
|
-
unify stream, Array.new(5) { Dataflow::Variable.new }
|
|
6
|
-
|
|
7
|
-
Thread.new { unify doubles, stream.map {|n| n*2 } }
|
|
8
|
-
Thread.new { unify triples, stream.map {|n| n*3 } }
|
|
9
|
-
Thread.new { unify squares, stream.map {|n| n**2 } }
|
|
10
|
-
|
|
11
|
-
Thread.new { stream.each {|x| unify x, rand(100) } }
|
|
12
|
-
|
|
13
|
-
puts "original: #{stream.inspect}"
|
|
14
|
-
puts "doubles: #{doubles.inspect}"
|
|
15
|
-
puts "triples: #{triples.inspect}"
|
|
16
|
-
puts "squares: #{squares.inspect}"
|
|
17
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
require 'net/http'
|
|
3
|
-
include Dataflow
|
|
4
|
-
|
|
5
|
-
# Be gentle running this one
|
|
6
|
-
Thread.abort_on_exception = true
|
|
7
|
-
local do |stream, branding_occurences, number_of_mentions|
|
|
8
|
-
unify stream, Array.new(10) { Dataflow::Variable.new }
|
|
9
|
-
stream.each {|s| Thread.new(s) {|v| unify v, Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
|
|
10
|
-
Thread.new { unify branding_occurences, stream.map {|http_body| http_body.scan /cuil/ } }
|
|
11
|
-
Thread.new { unify number_of_mentions, branding_occurences.map {|occurences| occurences.length } }
|
|
12
|
-
puts number_of_mentions.inspect
|
|
13
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
include Dataflow
|
|
3
|
-
|
|
4
|
-
# flow without parameters
|
|
5
|
-
local do |x|
|
|
6
|
-
flow do
|
|
7
|
-
# other stuff
|
|
8
|
-
unify x, 1337
|
|
9
|
-
end
|
|
10
|
-
puts x
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# flow with an output parameter
|
|
14
|
-
local do |x|
|
|
15
|
-
flow(x) do
|
|
16
|
-
# other stuff
|
|
17
|
-
1337
|
|
18
|
-
end
|
|
19
|
-
puts x
|
|
20
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
require 'net/http'
|
|
3
|
-
include Dataflow
|
|
4
|
-
|
|
5
|
-
# Be gentle running this one
|
|
6
|
-
Thread.abort_on_exception = true
|
|
7
|
-
local do |stream, branding_occurences, number_of_mentions|
|
|
8
|
-
unify stream, Array.new(10) { need_later { Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
|
|
9
|
-
unify branding_occurences, need_later { stream.map {|http_body| http_body.scan /cuil/ } }
|
|
10
|
-
unify number_of_mentions, need_later { branding_occurences.map {|occurences| occurences.length } }
|
|
11
|
-
puts number_of_mentions.inspect
|
|
12
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
include Dataflow
|
|
3
|
-
|
|
4
|
-
local do |queue, first, second|
|
|
5
|
-
unify queue, Dataflow::FutureQueue.new
|
|
6
|
-
queue.pop first
|
|
7
|
-
queue.push 1
|
|
8
|
-
queue.push 2
|
|
9
|
-
queue.pop second
|
|
10
|
-
puts "first: #{first}, second: #{second}"
|
|
11
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../dataflow"
|
|
2
|
-
|
|
3
|
-
class AnimalHouse
|
|
4
|
-
include Dataflow
|
|
5
|
-
declare :small_cat, :big_cat
|
|
6
|
-
|
|
7
|
-
def fetch_big_cat
|
|
8
|
-
Thread.new { unify big_cat, small_cat.upcase }
|
|
9
|
-
unify small_cat, 'cat'
|
|
10
|
-
big_cat
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
puts AnimalHouse.new.fetch_big_cat
|
|
15
|
-
|