contextr 0.1.9 → 1.0.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.tar.gz.sig +0 -0
- data/History.txt +8 -0
- data/Manifest.txt +12 -17
- data/README.txt +0 -1
- data/examples/employer.rb +229 -0
- data/examples/node.rb +213 -0
- data/lib/contextr/class_methods.rb +14 -6
- data/lib/contextr/core_ext/module.rb +3 -2
- data/lib/contextr/event_machine.rb +12 -12
- data/lib/contextr/inner_class.rb +7 -3
- data/lib/contextr/layer.rb +17 -7
- data/lib/contextr/public_api.rb +44 -3
- data/lib/contextr/version.rb +3 -3
- data/lib/ext/active_support_subset.rb +0 -45
- data/spec/contextr_spec.rb +97 -7
- data/test/{test_class_side.mkd → class_side.mkd} +6 -13
- data/test/{test_dynamic_scope.mkd → dynamic_scope.mkd} +2 -2
- data/test/{test_dynamics.mkd → dynamics.mkd} +3 -3
- data/test/{test_hello_world.mkd → hello_world.mkd} +1 -1
- data/test/{test_introduction.mkd → introduction.mkd} +4 -4
- data/test/{test_layer_state.mkd → layer_state.mkd} +2 -2
- data/test/lib/example_test.rb +2 -2
- data/test/lib/literate_maruku_test.rb +11 -9
- data/test/{test_meta_api.mkd → meta_api.mkd} +1 -1
- data/test/method_missing.mkd +40 -0
- data/test/{test_ordering.mkd → ordering.mkd} +8 -8
- data/test/restrictions.mkd +177 -0
- data/test/test_contextr.rb +7 -0
- data/test/test_plain.rb +92 -0
- metadata +17 -29
- metadata.gz.sig +0 -0
- data/test/lib/literate_markaby_test.rb +0 -97
- data/test/test_class_side.rb +0 -4
- data/test/test_dynamic_scope.rb +0 -4
- data/test/test_dynamics.rb +0 -4
- data/test/test_hello_world.rb +0 -4
- data/test/test_introduction.rb +0 -4
- data/test/test_layer_state.rb +0 -3
- data/test/test_meta_api.rb +0 -4
- data/test/test_ordering.rb +0 -3
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -5,6 +5,8 @@ Manifest.txt
|
|
5
5
|
README.txt
|
6
6
|
Rakefile
|
7
7
|
examples/README
|
8
|
+
examples/employer.rb
|
9
|
+
examples/node.rb
|
8
10
|
lib/contextr.rb
|
9
11
|
lib/contextr/class_methods.rb
|
10
12
|
lib/contextr/core_ext.rb
|
@@ -24,24 +26,17 @@ setup.rb
|
|
24
26
|
spec/contextr_spec.rb
|
25
27
|
spec/spec.opts
|
26
28
|
spec/spec_helper.rb
|
29
|
+
test/class_side.mkd
|
30
|
+
test/dynamic_scope.mkd
|
31
|
+
test/dynamics.mkd
|
32
|
+
test/hello_world.mkd
|
33
|
+
test/introduction.mkd
|
34
|
+
test/layer_state.mkd
|
27
35
|
test/lib/example_test.rb
|
28
|
-
test/lib/literate_markaby_test.rb
|
29
36
|
test/lib/literate_maruku_test.rb
|
30
|
-
test/
|
31
|
-
test/
|
37
|
+
test/meta_api.mkd
|
38
|
+
test/method_missing.mkd
|
39
|
+
test/ordering.mkd
|
40
|
+
test/restrictions.mkd
|
32
41
|
test/test_contextr.rb
|
33
|
-
test/test_dynamic_scope.mkd
|
34
|
-
test/test_dynamic_scope.rb
|
35
|
-
test/test_dynamics.mkd
|
36
|
-
test/test_dynamics.rb
|
37
|
-
test/test_hello_world.mkd
|
38
|
-
test/test_hello_world.rb
|
39
42
|
test/test_helper.rb
|
40
|
-
test/test_introduction.mkd
|
41
|
-
test/test_introduction.rb
|
42
|
-
test/test_layer_state.mkd
|
43
|
-
test/test_layer_state.rb
|
44
|
-
test/test_meta_api.mkd
|
45
|
-
test/test_meta_api.rb
|
46
|
-
test/test_ordering.mkd
|
47
|
-
test/test_ordering.rb
|
data/README.txt
CHANGED
@@ -6,7 +6,6 @@ Inspired by ContextL (Pascal Costanza) and ContextS (Robert Hirschfeld) with
|
|
6
6
|
thanks to Christian Neukirchen for giving the name and lots of ideas.
|
7
7
|
|
8
8
|
For more information see
|
9
|
-
- http://contextr.rubyforge.org/
|
10
9
|
- http://www.contextr.org/ or
|
11
10
|
- http://www.swa.hpi.uni-potsdam.de/cop/
|
12
11
|
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../lib/contextr"
|
2
|
+
|
3
|
+
module EasyInitializerMixin
|
4
|
+
def initialize(options = {})
|
5
|
+
options.each do |key, value|
|
6
|
+
self.send("#{key}=", value)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Employer
|
12
|
+
attr_accessor :name
|
13
|
+
include EasyInitializerMixin
|
14
|
+
end
|
15
|
+
class Person
|
16
|
+
attr_accessor :name, :employer
|
17
|
+
include EasyInitializerMixin
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class Employer
|
22
|
+
def to_s
|
23
|
+
"Employer\n" +
|
24
|
+
"Name: %s" % self.name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class Person
|
28
|
+
def to_s
|
29
|
+
"Person\n" +
|
30
|
+
"Name: %s" % self.name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Person
|
35
|
+
in_layer :employment do
|
36
|
+
def to_s
|
37
|
+
super + "\n%s" % yield(:receiver).employer
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Employer
|
43
|
+
attr_accessor :address
|
44
|
+
in_layer :detailed_info do
|
45
|
+
def to_s
|
46
|
+
super + "\n" +
|
47
|
+
"Address: %s" % yield(:receiver).address
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
class Person
|
52
|
+
attr_accessor :address
|
53
|
+
in_layer :detailed_info do
|
54
|
+
def to_s
|
55
|
+
super + "\n" +
|
56
|
+
"Address: %s" % yield(:receiver).address
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
vub = Employer.new
|
62
|
+
vub.name = "Vrije Universiteit Brussel"
|
63
|
+
vub.address = "Brussels"
|
64
|
+
pascal = Person.new
|
65
|
+
pascal.name = "Pascal"
|
66
|
+
pascal.employer = vub
|
67
|
+
pascal.address = "Brussels"
|
68
|
+
|
69
|
+
puts vub
|
70
|
+
puts
|
71
|
+
puts pascal
|
72
|
+
puts " - - - - - - - - "
|
73
|
+
|
74
|
+
ContextR::with_layer :employment do
|
75
|
+
puts vub
|
76
|
+
puts
|
77
|
+
puts pascal
|
78
|
+
puts " - - - - - - - - "
|
79
|
+
end
|
80
|
+
|
81
|
+
ContextR::with_layer :detailed_info do
|
82
|
+
puts vub
|
83
|
+
puts
|
84
|
+
puts pascal
|
85
|
+
puts " - - - - - - - - "
|
86
|
+
|
87
|
+
ContextR::with_layer :employment do
|
88
|
+
puts vub
|
89
|
+
puts
|
90
|
+
puts pascal
|
91
|
+
puts " - - - - - - - - "
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe ContextR do
|
96
|
+
it "should show all currently active layers" do
|
97
|
+
ContextR::with_layer :employment do
|
98
|
+
ContextR::active_layers.should == [:employment]
|
99
|
+
|
100
|
+
ContextR::with_layer :detailed_info do
|
101
|
+
ContextR::active_layers.should ==
|
102
|
+
[:detailed_info, :employment]
|
103
|
+
end
|
104
|
+
|
105
|
+
ContextR::active_layers.should == [:employment]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should show all layers ever used" do
|
110
|
+
ContextR::layers.should == [:employment, :detailed_info]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe ContextR do
|
115
|
+
it "should list all extended methods" do
|
116
|
+
Person.in_layer(:employment).instance_methods.should == ["to_s"]
|
117
|
+
Employer.in_layer(:employment).instance_methods.should be_empty
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
describe ContextR do
|
123
|
+
it "should execute later layers first, earlier layers later" do
|
124
|
+
ContextR::with_layer :detailed_info do
|
125
|
+
ContextR::with_layer :employment do
|
126
|
+
|
127
|
+
ContextR::active_layers.should ==
|
128
|
+
[:employment, :detailed_info]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
ContextR::with_layer :detailed_info, :employment do
|
133
|
+
|
134
|
+
ContextR::active_layers.should ==
|
135
|
+
[:employment, :detailed_info]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe ContextR do
|
141
|
+
it "should hide deactivated layers" do
|
142
|
+
ContextR::with_layer :detailed_info, :employment do
|
143
|
+
|
144
|
+
ContextR::active_layers.should ==
|
145
|
+
[:employment, :detailed_info]
|
146
|
+
|
147
|
+
ContextR::without_layer :employment do
|
148
|
+
ContextR::active_layers.should == [:detailed_info]
|
149
|
+
end
|
150
|
+
|
151
|
+
ContextR::without_layer :detailed_info do
|
152
|
+
ContextR::active_layers.should == [:employment]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe ContextR do
|
159
|
+
it "should update order at repetitive activation" do
|
160
|
+
ContextR::with_layer :detailed_info, :employment do
|
161
|
+
|
162
|
+
ContextR::active_layers.should == [:employment, :detailed_info]
|
163
|
+
|
164
|
+
ContextR::with_layer :detailed_info do
|
165
|
+
ContextR::active_layers.should == [:detailed_info, :employment]
|
166
|
+
end
|
167
|
+
|
168
|
+
ContextR::with_layer :employment do
|
169
|
+
ContextR::active_layers.should == [:employment, :detailed_info]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe ContextR do
|
176
|
+
it "should activate layer, even when they were explicitly deactivated" do
|
177
|
+
ContextR::with_layer :detailed_info, :employment do
|
178
|
+
ContextR::without_layer :employment do
|
179
|
+
ContextR::with_layer :employment do
|
180
|
+
ContextR::active_layers.should == [:employment, :detailed_info]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe ContextR do
|
188
|
+
def step(index, *layers)
|
189
|
+
@step += 1
|
190
|
+
@step.should == index
|
191
|
+
ContextR::active_layers.should == layers
|
192
|
+
end
|
193
|
+
|
194
|
+
def task_one
|
195
|
+
@mutex.lock
|
196
|
+
ContextR::with_layer :employment do
|
197
|
+
step(2, :employment, :detailed_info)
|
198
|
+
@mutex.unlock
|
199
|
+
sleep(0.1)
|
200
|
+
@mutex.lock
|
201
|
+
step(4, :employment, :detailed_info)
|
202
|
+
end
|
203
|
+
@mutex.unlock
|
204
|
+
end
|
205
|
+
|
206
|
+
def task_two
|
207
|
+
@mutex.lock
|
208
|
+
step(3, :detailed_info)
|
209
|
+
@mutex.unlock
|
210
|
+
end
|
211
|
+
|
212
|
+
before do
|
213
|
+
@mutex = Mutex.new
|
214
|
+
@step = 0
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should consider dynamic scope" do
|
218
|
+
ContextR::with_layer :detailed_info do
|
219
|
+
step(1, :detailed_info)
|
220
|
+
|
221
|
+
one = Thread.new { task_one }
|
222
|
+
two = Thread.new { task_two }
|
223
|
+
|
224
|
+
one.join
|
225
|
+
two.join
|
226
|
+
step(5, :detailed_info)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
data/examples/node.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "contextr"
|
3
|
+
|
4
|
+
module Cop
|
5
|
+
# Fig. 3
|
6
|
+
class Node
|
7
|
+
attr_accessor :first, :op, :second
|
8
|
+
|
9
|
+
def initialize(values = {})
|
10
|
+
values.each do |key, value|
|
11
|
+
self.send("#{key}=", value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Leaf
|
16
|
+
attr_accessor :value
|
17
|
+
def initialize(value)
|
18
|
+
self.value = value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Fig. 4
|
23
|
+
class ExampleTree
|
24
|
+
def initialize
|
25
|
+
@tree = Node.new(
|
26
|
+
:first => Node.new(
|
27
|
+
:first => Node.new(
|
28
|
+
:first => Leaf.new(1),
|
29
|
+
:op => :+,
|
30
|
+
:second => Leaf.new(2)),
|
31
|
+
:op => :*,
|
32
|
+
:second => Node.new(
|
33
|
+
:first => Leaf.new(3),
|
34
|
+
:op => :-,
|
35
|
+
:second => Leaf.new(4))),
|
36
|
+
:op => :/,
|
37
|
+
:second => Leaf.new(5))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fig. 5
|
42
|
+
class Node
|
43
|
+
def evaluate
|
44
|
+
# first.evaluate.send(op, second.evaluate.to_f)
|
45
|
+
first.evaluate.send(op, second.evaluate)
|
46
|
+
end
|
47
|
+
def print_prefix
|
48
|
+
"(#{op}#{first.print_prefix}#{second.print_prefix})"
|
49
|
+
end
|
50
|
+
def print_infix
|
51
|
+
"(#{first.print_infix}#{op}#{second.print_infix})"
|
52
|
+
end
|
53
|
+
def print_postfix
|
54
|
+
"(#{first.print_postfix}#{second.print_postfix}#{op})"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Leaf
|
59
|
+
def evaluate
|
60
|
+
value
|
61
|
+
end
|
62
|
+
def print_infix
|
63
|
+
value.to_s
|
64
|
+
end
|
65
|
+
def print_postfix
|
66
|
+
value.to_s
|
67
|
+
end
|
68
|
+
def print_prefix
|
69
|
+
value.to_s
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Fig. 7
|
74
|
+
class ExampleTree
|
75
|
+
def show
|
76
|
+
puts @tree.print_infix
|
77
|
+
puts @tree.print_prefix
|
78
|
+
puts @tree.print_postfix
|
79
|
+
puts @tree.evaluate
|
80
|
+
end
|
81
|
+
end
|
82
|
+
ExampleTree.new.show
|
83
|
+
|
84
|
+
# Fig. 8
|
85
|
+
class Node
|
86
|
+
def accept(visitor)
|
87
|
+
visitor.visit(self)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
class Leaf
|
91
|
+
def accept(visitor)
|
92
|
+
visitor.visit(self)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Fig. 9
|
97
|
+
class Visitor
|
98
|
+
def visit(node_or_leaf)
|
99
|
+
case node_or_leaf
|
100
|
+
when Node
|
101
|
+
visit_node(node_or_leaf)
|
102
|
+
when Leaf
|
103
|
+
visit_leaf(node_or_leaf)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
class PrintPrefixVisitor < Visitor
|
108
|
+
def visit_leaf(leaf)
|
109
|
+
leaf.value.to_s
|
110
|
+
end
|
111
|
+
def visit_node(node)
|
112
|
+
"(#{node.op}#{node.first.accept(self)}#{node.second.accept(self)})"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
class PrintInfixVisitor < Visitor
|
116
|
+
def visit_leaf(leaf)
|
117
|
+
leaf.value.to_s
|
118
|
+
end
|
119
|
+
def visit_node(node)
|
120
|
+
"(#{node.first.accept(self)}#{node.op}#{node.second.accept(self)})"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
class PrintPostfixVisitor < Visitor
|
124
|
+
def visit_leaf(leaf)
|
125
|
+
leaf.value.to_s
|
126
|
+
end
|
127
|
+
def visit_node(node)
|
128
|
+
"(#{node.first.accept(self)}#{node.second.accept(self)}#{node.op})"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
class EvaluateVisitor < Visitor
|
132
|
+
def visit_leaf(leaf)
|
133
|
+
leaf.value
|
134
|
+
end
|
135
|
+
def visit_node(node)
|
136
|
+
# node.first.accept(self).send(node.op, node.second.accept(self).to_f)
|
137
|
+
node.first.accept(self).send(node.op, node.second.accept(self))
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Fig. 10
|
142
|
+
class ExampleTree
|
143
|
+
def show_visitor
|
144
|
+
puts @tree.accept(PrintInfixVisitor.new)
|
145
|
+
puts @tree.accept(PrintPrefixVisitor.new)
|
146
|
+
puts @tree.accept(PrintPostfixVisitor.new)
|
147
|
+
puts @tree.accept(EvaluateVisitor.new)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
ExampleTree.new.show_visitor
|
151
|
+
|
152
|
+
# Fig. 11
|
153
|
+
class Leaf
|
154
|
+
in_layer :print_prefix do
|
155
|
+
def to_s
|
156
|
+
yield(:receiver).value.to_s
|
157
|
+
end
|
158
|
+
end
|
159
|
+
in_layer :print_infix do
|
160
|
+
def to_s
|
161
|
+
yield(:receiver).value.to_s
|
162
|
+
end
|
163
|
+
end
|
164
|
+
in_layer :print_postfix do
|
165
|
+
def to_s
|
166
|
+
yield(:receiver).value.to_s
|
167
|
+
end
|
168
|
+
end
|
169
|
+
in_layer :evaluate do
|
170
|
+
def evaluate
|
171
|
+
yield(:receiver).value
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
class Node
|
176
|
+
in_layer :print_prefix do
|
177
|
+
def to_s
|
178
|
+
node = yield(:receiver)
|
179
|
+
"(#{node.op}#{node.first}#{node.second})"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
in_layer :print_infix do
|
183
|
+
def to_s
|
184
|
+
node = yield(:receiver)
|
185
|
+
"(#{node.first}#{node.op}#{node.second})"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
in_layer :print_postfix do
|
189
|
+
def to_s
|
190
|
+
node = yield(:receiver)
|
191
|
+
"(#{node.first}#{node.second}#{node.op})"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
in_layer :evaluate do
|
195
|
+
def evaluate
|
196
|
+
node = yield(:receiver)
|
197
|
+
# node.first.evaluate.send(node.op, node.second.evaluate.to_f)
|
198
|
+
node.first.evaluate.send(node.op, node.second.evaluate)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Fig. 12
|
204
|
+
class ExampleTree
|
205
|
+
def show_layers
|
206
|
+
ContextR::with_layer(:print_infix) { puts @tree }
|
207
|
+
ContextR::with_layer(:print_prefix) { puts @tree }
|
208
|
+
ContextR::with_layer(:print_postfix) { puts @tree }
|
209
|
+
ContextR::with_layer(:evaluate) { puts @tree.evaluate }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
ExampleTree.new.show_layers
|
213
|
+
end
|