contextr 0.0.2 → 0.0.3
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.txt +8 -1
- data/Manifest.txt +2 -0
- data/Rakefile +9 -1
- data/examples/fibonacci.rb +53 -52
- data/examples/with_current_context.rb +29 -0
- data/lib/contextr.rb +6 -2
- data/lib/contextr/contextr.rb +70 -0
- data/lib/contextr/layer.rb +7 -2
- data/lib/contextr/version.rb +1 -1
- data/spec/contextr/contextr_api_spec.rb +56 -8
- data/spec/contextr/contextr_class_side_spec.rb +77 -0
- data/spec/contextr/contextr_functional_spec.rb +18 -19
- data/spec/core_ext/module_spec.rb +27 -25
- data/spec/core_ext/proc_spec.rb +14 -14
- data/website/index.html +10 -4
- data/website/index.txt +2 -1
- data/website/template.rhtml +6 -1
- metadata +15 -7
data/History.txt
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
+++ 0.0.3 2007-05-22
|
2
|
+
|
3
|
+
+ 3 major changes
|
4
|
+
+ Added #add_context_sensor and #with_current_context
|
5
|
+
+ Added #activate_layers and #deactivate_layers
|
6
|
+
+ Added support for class side methods
|
7
|
+
|
1
8
|
+++ 0.0.2 2007-05-08
|
2
9
|
|
3
10
|
+ 1 major change:
|
4
|
-
+ Changed the wrapper execution order to a
|
11
|
+
+ Changed the wrapper execution order to a hopefully more natural ordering
|
5
12
|
+ Added documentation
|
6
13
|
+ 1 minor change:
|
7
14
|
+ finished transition from unit tests to rspec based specification
|
data/Manifest.txt
CHANGED
@@ -6,6 +6,7 @@ README.txt
|
|
6
6
|
Rakefile
|
7
7
|
examples/education.rb
|
8
8
|
examples/fibonacci.rb
|
9
|
+
examples/with_current_context.rb
|
9
10
|
lib/contextr.rb
|
10
11
|
lib/contextr/contextr.rb
|
11
12
|
lib/contextr/layer.rb
|
@@ -20,6 +21,7 @@ rake/specific_group_spec_task.rb
|
|
20
21
|
scripts/txt2html
|
21
22
|
setup.rb
|
22
23
|
spec/contextr/contextr_api_spec.rb
|
24
|
+
spec/contextr/contextr_class_side_spec.rb
|
23
25
|
spec/contextr/contextr_functional_spec.rb
|
24
26
|
spec/core_ext/module_spec.rb
|
25
27
|
spec/core_ext/proc_spec.rb
|
data/Rakefile
CHANGED
@@ -68,7 +68,7 @@ task :website_upload do
|
|
68
68
|
remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
|
69
69
|
# remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
70
|
local_dir = 'website'
|
71
|
-
sh %{rsync -av --
|
71
|
+
sh %{rsync -av --exclude=".*/" #{local_dir}/ #{host}:#{remote_dir}}
|
72
72
|
end
|
73
73
|
|
74
74
|
desc 'Generate and upload website files'
|
@@ -88,6 +88,14 @@ task :check_version do
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
+
#desc 'Submit the docs HTML files to RubyForge'
|
92
|
+
#task :docs_publish => [ :docs ] do
|
93
|
+
# config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
94
|
+
# host = "#{config["username"]}@rubyforge.org"
|
95
|
+
# remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/api"
|
96
|
+
# local_dir = 'doc'
|
97
|
+
# sh %{rsync -av --delete-excluded --exclude=".*/" #{local_dir}/ #{host}:#{remote_dir}}
|
98
|
+
#end
|
91
99
|
|
92
100
|
# Most of this code was taken from the Rubinius Rakefile.
|
93
101
|
# Thanks for the help.
|
data/examples/fibonacci.rb
CHANGED
@@ -4,39 +4,41 @@ require "contextr"
|
|
4
4
|
require 'test/unit'
|
5
5
|
require 'benchmark'
|
6
6
|
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
fixnum
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
class Fibonacci
|
8
|
+
class << self
|
9
|
+
def compute fixnum
|
10
|
+
if fixnum == 1 or fixnum == 0
|
11
|
+
fixnum
|
12
|
+
elsif fixnum < 0
|
13
|
+
raise ArgumentError, "Fibonacci not defined for negative numbers"
|
14
|
+
else
|
15
|
+
compute(fixnum - 1) + compute(fixnum - 2)
|
16
|
+
end
|
15
17
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
attr_accessor :cache
|
18
|
+
|
19
|
+
layer :fib_pre_post, :fib_wrap
|
20
|
+
attr_accessor :cache
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
fib_pre_post.pre :compute do | nature |
|
23
|
+
self.cache ||= {}
|
24
|
+
if self.cache.key? nature.arguments.first
|
25
|
+
nature.break! self.cache[nature.arguments.first]
|
26
|
+
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
self.cache[nature.arguments.first] = nature.return_value
|
30
|
-
end
|
31
|
-
|
32
|
-
fib_wrap.wrap :compute do | nature |
|
33
|
-
self.cache ||= {}
|
34
|
-
if self.cache.key? nature.arguments.first
|
35
|
-
nature.return_value = self.cache[nature.arguments.first]
|
36
|
-
else
|
37
|
-
nature.call_next
|
29
|
+
fib_pre_post.post :compute do | nature |
|
38
30
|
self.cache[nature.arguments.first] = nature.return_value
|
39
31
|
end
|
32
|
+
|
33
|
+
fib_wrap.wrap :compute do | nature |
|
34
|
+
self.cache ||= {}
|
35
|
+
if self.cache.key? nature.arguments.first
|
36
|
+
nature.return_value = self.cache[nature.arguments.first]
|
37
|
+
else
|
38
|
+
nature.call_next
|
39
|
+
self.cache[nature.arguments.first] = nature.return_value
|
40
|
+
end
|
41
|
+
end
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
@@ -58,17 +60,17 @@ end
|
|
58
60
|
|
59
61
|
class FibonacciTest < Test::Unit::TestCase
|
60
62
|
def setup
|
61
|
-
|
63
|
+
Fibonacci.cache = {}
|
62
64
|
end
|
63
65
|
|
64
66
|
def test_basic_function
|
65
67
|
Benchmark.bm(20) do |x|
|
66
68
|
x.report("Recursive:") {
|
67
|
-
assert_equal 0,
|
68
|
-
assert_equal 1,
|
69
|
-
assert_equal 1,
|
70
|
-
assert_equal 55,
|
71
|
-
assert_equal 6765,
|
69
|
+
assert_equal 0, Fibonacci.compute( 0 )
|
70
|
+
assert_equal 1, Fibonacci.compute( 1 )
|
71
|
+
assert_equal 1, Fibonacci.compute( 2 )
|
72
|
+
assert_equal 55, Fibonacci.compute( 10 )
|
73
|
+
assert_equal 6765, Fibonacci.compute( 20 )
|
72
74
|
# The following are too hard for the simple solution
|
73
75
|
assert_equal 75_025, 25.fibonacci
|
74
76
|
assert_equal 9227465, 35.fibonacci
|
@@ -84,18 +86,17 @@ class FibonacciTest < Test::Unit::TestCase
|
|
84
86
|
Benchmark.bm(20) do |x|
|
85
87
|
x.report("Layered Pre/Post:") {
|
86
88
|
ContextR.with_layers :fib_pre_post do
|
87
|
-
assert_equal 0,
|
88
|
-
assert_equal 1,
|
89
|
-
assert_equal 1,
|
90
|
-
assert_equal
|
91
|
-
assert_equal
|
92
|
-
assert_equal
|
93
|
-
assert_equal
|
94
|
-
assert_equal 9227465, @fibonacci.compute( 35 )
|
89
|
+
assert_equal 0, Fibonacci.compute( 0 )
|
90
|
+
assert_equal 1, Fibonacci.compute( 1 )
|
91
|
+
assert_equal 1, Fibonacci.compute( 2 )
|
92
|
+
assert_equal 55, Fibonacci.compute( 10 )
|
93
|
+
assert_equal 6765, Fibonacci.compute( 20 )
|
94
|
+
assert_equal 75_025, Fibonacci.compute( 25 )
|
95
|
+
assert_equal 9227465, Fibonacci.compute( 35 )
|
95
96
|
assert_equal 280571172992510140037611932413038677189525,
|
96
|
-
|
97
|
+
Fibonacci.compute( 200 )
|
97
98
|
assert_equal 176023680645013966468226945392411250770384383304492191886725992896575345044216019675,
|
98
|
-
|
99
|
+
Fibonacci.compute( 400 )
|
99
100
|
end
|
100
101
|
}
|
101
102
|
end
|
@@ -105,17 +106,17 @@ class FibonacciTest < Test::Unit::TestCase
|
|
105
106
|
Benchmark.bm(20) do |x|
|
106
107
|
x.report("Layered Wrap:") {
|
107
108
|
ContextR.with_layers :fib_wrap do
|
108
|
-
assert_equal 0,
|
109
|
-
assert_equal 1,
|
110
|
-
assert_equal 1,
|
111
|
-
assert_equal 55,
|
112
|
-
assert_equal 6765,
|
113
|
-
assert_equal 75_025,
|
114
|
-
assert_equal 9227465,
|
109
|
+
assert_equal 0, Fibonacci.compute( 0 )
|
110
|
+
assert_equal 1, Fibonacci.compute( 1 )
|
111
|
+
assert_equal 1, Fibonacci.compute( 2 )
|
112
|
+
assert_equal 55, Fibonacci.compute( 10 )
|
113
|
+
assert_equal 6765, Fibonacci.compute( 20 )
|
114
|
+
assert_equal 75_025, Fibonacci.compute( 25 )
|
115
|
+
assert_equal 9227465, Fibonacci.compute( 35 )
|
115
116
|
assert_equal 280571172992510140037611932413038677189525,
|
116
|
-
|
117
|
+
Fibonacci.compute( 200 )
|
117
118
|
assert_equal 176023680645013966468226945392411250770384383304492191886725992896575345044216019675,
|
118
|
-
|
119
|
+
Fibonacci.compute( 400 )
|
119
120
|
end
|
120
121
|
}
|
121
122
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "contextr"
|
3
|
+
|
4
|
+
class A
|
5
|
+
class << self
|
6
|
+
def a
|
7
|
+
"a"
|
8
|
+
end
|
9
|
+
|
10
|
+
layer :foo
|
11
|
+
|
12
|
+
foo.post :a do | n |
|
13
|
+
n.return_value << " post"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ContextR::add_context_sensor do
|
19
|
+
[:foo]
|
20
|
+
end
|
21
|
+
|
22
|
+
puts A.a # => "a"
|
23
|
+
ContextR::with_layer :foo do
|
24
|
+
puts A.a # => "a post"
|
25
|
+
end
|
26
|
+
ContextR::with_current_context do
|
27
|
+
puts A.a # => "a post"
|
28
|
+
end
|
29
|
+
puts A.a # => "a"
|
data/lib/contextr.rb
CHANGED
@@ -2,8 +2,12 @@
|
|
2
2
|
# TODO: get rid of this workaround to avoid double loading on `rake test`
|
3
3
|
#++
|
4
4
|
unless Object.const_defined? "ContextR"
|
5
|
-
|
6
|
-
|
5
|
+
if RUBY_VERSION == "1.9.0"
|
6
|
+
require File.dirname(__FILE__) + '/activesupport/lib/active_support'
|
7
|
+
else
|
8
|
+
require 'rubygems'
|
9
|
+
require 'active_support'
|
10
|
+
end
|
7
11
|
|
8
12
|
Dir[File.join(File.dirname(__FILE__), 'ext/**/*.rb')].sort.each { |lib| require lib }
|
9
13
|
Dir[File.join(File.dirname(__FILE__), 'core_ext/**/*.rb')].sort.each { |lib| require lib }
|
data/lib/contextr/contextr.rb
CHANGED
@@ -26,6 +26,23 @@ module ContextR
|
|
26
26
|
end
|
27
27
|
Dynamic.let( { :layers => Dynamic[:layers] | layers }, &block )
|
28
28
|
end
|
29
|
+
alias with_layer with_layers
|
30
|
+
|
31
|
+
# allows the explicit activation of layers
|
32
|
+
#
|
33
|
+
# ContextR::activate_layers( :foo, :bar )
|
34
|
+
# ContextR::current_layers # => [:default, :foo, :bar]
|
35
|
+
#
|
36
|
+
# :call-seq:
|
37
|
+
# deactivate_layers( layer_name, ... )
|
38
|
+
#
|
39
|
+
def activate_layers( *layer_symbols )
|
40
|
+
layers = layer_symbols.collect do | layer_symbol |
|
41
|
+
ContextR.layer_by_name( ContextR.layerize( layer_symbol ) )
|
42
|
+
end
|
43
|
+
Dynamic[:layers] |= layers
|
44
|
+
end
|
45
|
+
alias activate_layer activate_layers
|
29
46
|
|
30
47
|
# allows the explicit deactivation of layers within a block context
|
31
48
|
#
|
@@ -47,6 +64,26 @@ module ContextR
|
|
47
64
|
end
|
48
65
|
Dynamic.let( { :layers => Dynamic[:layers] - layers }, &block )
|
49
66
|
end
|
67
|
+
alias without_layer without_layers
|
68
|
+
|
69
|
+
# allows the explicit deactivation of layers
|
70
|
+
#
|
71
|
+
# ContextR::activate_layers( :foo, :bar )
|
72
|
+
# ContextR::current_layers # => [:default, :foo, :bar]
|
73
|
+
#
|
74
|
+
# ContextR::deactivate_layers( :foo )
|
75
|
+
# ContextR::current_layers # => [:default, :bar]
|
76
|
+
#
|
77
|
+
# :call-seq:
|
78
|
+
# deactivate_layers( layer_name, ... )
|
79
|
+
#
|
80
|
+
def deactivate_layers( *layer_symbols )
|
81
|
+
layers = layer_symbols.collect do | layer_symbol |
|
82
|
+
ContextR.layer_by_name( ContextR.layerize( layer_symbol ) )
|
83
|
+
end
|
84
|
+
Dynamic[:layers] -= layers
|
85
|
+
end
|
86
|
+
alias deactivate_layer deactivate_layers
|
50
87
|
|
51
88
|
# returns the names of the currently activated layers
|
52
89
|
#
|
@@ -59,6 +96,39 @@ module ContextR
|
|
59
96
|
Dynamic[:layers].collect{ | layer_class | self.symbolize( layer_class ) }
|
60
97
|
end
|
61
98
|
|
99
|
+
# allows the registration of context sensors. These are blocks that are
|
100
|
+
# called on with_current_context and should return a list of layers, that
|
101
|
+
# should be activated.
|
102
|
+
#
|
103
|
+
# ContextR::add_context_sensor do
|
104
|
+
# # some clever code computes some layers to activate
|
105
|
+
# [ :foo ]
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# :call-seq:
|
109
|
+
# add_context_sensor() { ... }
|
110
|
+
#
|
111
|
+
def add_context_sensor &block
|
112
|
+
@sensors ||= []
|
113
|
+
@sensors << block
|
114
|
+
end
|
115
|
+
|
116
|
+
# asks all sensors to compute the current context, e.g. layers that should
|
117
|
+
# be active, and executes the given block in the context. It works basically
|
118
|
+
# like with_layers
|
119
|
+
#
|
120
|
+
# :call-seq:
|
121
|
+
# with_current_context() { ... }
|
122
|
+
#
|
123
|
+
def with_current_context(&block)
|
124
|
+
layers = @sensors.inject([]) do | akku, sensor |
|
125
|
+
akku | sensor.call
|
126
|
+
end
|
127
|
+
ContextR::with_layers(*layers) do
|
128
|
+
block.call
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
62
132
|
def symbolize( layer_klass ) # :nodoc:
|
63
133
|
layer_klass.namespace_free_name.gsub( "Layer", "" ).downcase.to_sym
|
64
134
|
end
|
data/lib/contextr/layer.rb
CHANGED
@@ -79,7 +79,7 @@ module ContextR
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def inherited( new_base_layer )
|
82
|
-
unless new_base_layer.name.empty?
|
82
|
+
unless new_base_layer.name.nil? or new_base_layer.name.empty?
|
83
83
|
base_layers[ContextR::symbolize( new_base_layer )] = new_base_layer
|
84
84
|
end
|
85
85
|
end
|
@@ -146,8 +146,13 @@ module ContextR
|
|
146
146
|
|
147
147
|
def extended( object )
|
148
148
|
self.extended_objects ||= Hash.new do | cache, object |
|
149
|
+
object_class = if object.kind_of? Class
|
150
|
+
(class << object; self; end)
|
151
|
+
else
|
152
|
+
object.class
|
153
|
+
end
|
149
154
|
cache[ object ] =
|
150
|
-
ExtendedObject.new( object, self.methods_of(
|
155
|
+
ExtendedObject.new( object, self.methods_of( object_class ) )
|
151
156
|
end
|
152
157
|
self.extended_objects[object]
|
153
158
|
end
|
data/lib/contextr/version.rb
CHANGED
@@ -9,8 +9,8 @@ class ContextRApiFoo
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
describe 'Each class' do
|
13
|
+
it 'should provide a method to enable a single layer' do
|
14
14
|
lambda do
|
15
15
|
class ContextRApiFoo
|
16
16
|
layer :bar
|
@@ -18,7 +18,7 @@ context 'Each class' do
|
|
18
18
|
end.should_not raise_error
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
it 'should provide a method to access these layers by name' do
|
22
22
|
begin
|
23
23
|
class ContextRApiFoo
|
24
24
|
bar
|
@@ -27,8 +27,8 @@ context 'Each class' do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
describe 'Each layer in a class' do
|
31
|
+
it 'should allow the definition of pre method wrappers ' +
|
32
32
|
'with `pre`' do
|
33
33
|
lambda do
|
34
34
|
class ContextRApiFoo
|
@@ -39,7 +39,7 @@ context 'Each layer in a class' do
|
|
39
39
|
end
|
40
40
|
end.should_not raise_error
|
41
41
|
end
|
42
|
-
|
42
|
+
it 'should allow the definition of post method wrappers ' +
|
43
43
|
'with `post`' do
|
44
44
|
lambda do
|
45
45
|
class ContextRApiFoo
|
@@ -50,7 +50,7 @@ context 'Each layer in a class' do
|
|
50
50
|
end
|
51
51
|
end.should_not raise_error
|
52
52
|
end
|
53
|
-
|
53
|
+
it 'should allow the definition of around method wrappers ' +
|
54
54
|
'with `around`' do
|
55
55
|
lambda do
|
56
56
|
class ContextRApiFoo
|
@@ -62,7 +62,7 @@ context 'Each layer in a class' do
|
|
62
62
|
end
|
63
63
|
end.should_not raise_error
|
64
64
|
end
|
65
|
-
|
65
|
+
it 'should allow the definition of around method wrappers ' +
|
66
66
|
'with `wrap`' do
|
67
67
|
lambda do
|
68
68
|
class ContextRApiFoo
|
@@ -76,3 +76,51 @@ context 'Each layer in a class' do
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
describe ContextR do
|
80
|
+
it "should activate layers with activate_layers" do
|
81
|
+
ContextR::activate_layers :foo
|
82
|
+
ContextR::current_layers.should include(:foo)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should activate multiple layers wiht activate_layers" do
|
86
|
+
ContextR::activate_layers :bar, :baz
|
87
|
+
ContextR::current_layers.should include(:foo)
|
88
|
+
ContextR::current_layers.should include(:bar)
|
89
|
+
ContextR::current_layers.should include(:baz)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should deactivate layers with activate_layers" do
|
93
|
+
ContextR::deactivate_layers :bar
|
94
|
+
ContextR::current_layers.should_not include(:bar)
|
95
|
+
ContextR::current_layers.should include(:foo)
|
96
|
+
ContextR::current_layers.should include(:baz)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should deactivate multiple layers wiht activate_layers" do
|
100
|
+
ContextR::deactivate_layers :foo, :baz
|
101
|
+
ContextR::current_layers.should_not include(:bar)
|
102
|
+
ContextR::current_layers.should_not include(:foo)
|
103
|
+
ContextR::current_layers.should_not include(:baz)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should allow the registration of context sensors" do
|
107
|
+
lambda do
|
108
|
+
ContextR::add_context_sensor do
|
109
|
+
[:foo]
|
110
|
+
end
|
111
|
+
end.should_not raise_error
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should allow the use of with_current_context and use the sensors to " +
|
115
|
+
"compute it" do
|
116
|
+
ContextR::add_context_sensor do
|
117
|
+
[:bar]
|
118
|
+
end
|
119
|
+
lambda do
|
120
|
+
ContextR::with_current_context do
|
121
|
+
ContextR::current_layers.should include(:foo)
|
122
|
+
ContextR::current_layers.should include(:bar)
|
123
|
+
end
|
124
|
+
end.should_not raise_error
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper.rb"
|
2
|
+
|
3
|
+
class ContextRClassSide
|
4
|
+
class << self
|
5
|
+
def non_contextified_method
|
6
|
+
"non_contextified_method"
|
7
|
+
end
|
8
|
+
def pre_wrapped_method
|
9
|
+
"pre_wrapped_method"
|
10
|
+
end
|
11
|
+
def post_wrapped_method
|
12
|
+
"post_wrapped_method"
|
13
|
+
end
|
14
|
+
def around_wrapped_method
|
15
|
+
"around_wrapped_method"
|
16
|
+
end
|
17
|
+
|
18
|
+
layer :simple_wrappers, :dummy
|
19
|
+
|
20
|
+
simple_wrappers.pre :pre_wrapped_method do
|
21
|
+
@pre_wrapped_method_called = true
|
22
|
+
end
|
23
|
+
simple_wrappers.post :post_wrapped_method do
|
24
|
+
@post_wrapped_method_called = true
|
25
|
+
end
|
26
|
+
simple_wrappers.around :around_wrapped_method do | n |
|
27
|
+
@around_wrapped_method_called = true
|
28
|
+
n.call_next
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "A contextified class" do
|
34
|
+
it "should run a simple method " +
|
35
|
+
"*normally* when all layers are deactivated" do
|
36
|
+
ContextRClassSide.non_contextified_method.should ==
|
37
|
+
"non_contextified_method"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should run a simple method " +
|
41
|
+
"*normally* when any layer is activated" do
|
42
|
+
ContextR.with_layers( :simple_wrappers ) do
|
43
|
+
ContextRClassSide.non_contextified_method.should ==
|
44
|
+
"non_contextified_method"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
%w{pre post around}.each do | qualifier |
|
49
|
+
it "should run a #{qualifier}-ed method " +
|
50
|
+
"*normally* when all layers are deactivated" do
|
51
|
+
ContextRClassSide.send( "#{qualifier}_wrapped_method" ).should ==
|
52
|
+
"#{qualifier}_wrapped_method"
|
53
|
+
ContextRClassSide.instance_variables.should_not include(
|
54
|
+
"@#{qualifier}_wrapped_method_called" )
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should run a #{qualifier}-ed method " +
|
58
|
+
"*normally* when any layer is activated" do
|
59
|
+
ContextR.with_layers( :dummy ) do
|
60
|
+
ContextRClassSide.send( "#{qualifier}_wrapped_method" ).should ==
|
61
|
+
"#{qualifier}_wrapped_method"
|
62
|
+
ContextRClassSide.instance_variables.should_not include(
|
63
|
+
"@#{qualifier}_wrapped_method_called" )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should run a #{qualifier}-ed method with " +
|
68
|
+
"additional behaviour when a specific layer is activated" do
|
69
|
+
ContextR.with_layers( :simple_wrappers ) do
|
70
|
+
ContextRClassSide.send( "#{qualifier}_wrapped_method" ).should ==
|
71
|
+
"#{qualifier}_wrapped_method"
|
72
|
+
ContextRClassSide.instance_variables.should include(
|
73
|
+
"@#{qualifier}_wrapped_method_called" )
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -27,17 +27,17 @@ class SimpleWrapperClass
|
|
27
27
|
n.call_next
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
|
30
|
+
describe "An instance of a contextified class" do
|
31
|
+
before do
|
32
32
|
@instance = SimpleWrapperClass.new
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
it "should run a simple method " +
|
36
36
|
"*normally* when all layers are deactivated" do
|
37
37
|
@instance.non_contextified_method.should == "non_contextified_method"
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
it "should run a simple method " +
|
41
41
|
"*normally* when any layer is activated" do
|
42
42
|
ContextR.with_layers( :simple_wrappers ) do
|
43
43
|
@instance.non_contextified_method.should == "non_contextified_method"
|
@@ -45,42 +45,42 @@ context "An instance of a contextified class" do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
%w{pre post around}.each do | qualifier |
|
48
|
-
|
48
|
+
it "should run a #{qualifier}-ed method " +
|
49
49
|
"*normally* when all layers are deactivated" do
|
50
50
|
@instance.send( "#{qualifier}_wrapped_method" ).should ==
|
51
51
|
"#{qualifier}_wrapped_method"
|
52
|
-
@instance.instance_variables.
|
52
|
+
@instance.instance_variables.should_not include(
|
53
53
|
"@#{qualifier}_wrapped_method_called" )
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
it "should run a #{qualifier}-ed method " +
|
57
57
|
"*normally* when any layer is activated" do
|
58
58
|
ContextR.with_layers( :dummy ) do
|
59
59
|
@instance.send( "#{qualifier}_wrapped_method" ).should ==
|
60
60
|
"#{qualifier}_wrapped_method"
|
61
|
-
@instance.instance_variables.
|
61
|
+
@instance.instance_variables.should_not include(
|
62
62
|
"@#{qualifier}_wrapped_method_called" )
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
|
66
|
+
it "should run a #{qualifier}-ed method with " +
|
67
67
|
"additional behaviour when a specific layer is activated" do
|
68
68
|
ContextR.with_layers( :simple_wrappers ) do
|
69
69
|
@instance.send( "#{qualifier}_wrapped_method" ).should ==
|
70
70
|
"#{qualifier}_wrapped_method"
|
71
|
-
@instance.instance_variables.
|
71
|
+
@instance.instance_variables.should include(
|
72
72
|
"@#{qualifier}_wrapped_method_called" )
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
it "should run a #{qualifier}-ed method without additional " +
|
77
77
|
"behaviour when a specific layer is activated and afterwards " +
|
78
78
|
"deactivated" do
|
79
79
|
ContextR.with_layers( :simple_wrappers ) do
|
80
80
|
ContextR.without_layers( :simple_wrappers ) do
|
81
81
|
@instance.send( "#{qualifier}_wrapped_method" ).should ==
|
82
82
|
"#{qualifier}_wrapped_method"
|
83
|
-
@instance.instance_variables.
|
83
|
+
@instance.instance_variables.should_not include(
|
84
84
|
"@#{qualifier}_wrapped_method_called" )
|
85
85
|
end
|
86
86
|
end
|
@@ -253,11 +253,11 @@ around_multiple_spec = lambda do | instance |
|
|
253
253
|
end
|
254
254
|
|
255
255
|
%w{pre post around}.each do | qualifier |
|
256
|
-
|
257
|
-
|
256
|
+
describe "#{qualifier.capitalize} wrappers within a method" do
|
257
|
+
before do
|
258
258
|
@instance = NestedLayerActivationClass.new
|
259
259
|
end
|
260
|
-
|
260
|
+
it "should run in the sequence of nesting, when using nested " +
|
261
261
|
"activation" do
|
262
262
|
ContextR::with_layers :outer_layer do
|
263
263
|
ContextR::with_layers :inner_layer do
|
@@ -267,7 +267,7 @@ end
|
|
267
267
|
end
|
268
268
|
eval("#{qualifier}_spec").call( @instance )
|
269
269
|
end
|
270
|
-
|
270
|
+
it "should run in the sequence of nesting, when using simultaneous " +
|
271
271
|
"activation" do
|
272
272
|
ContextR::with_layers :outer_layer, :inner_layer do
|
273
273
|
@instance.send( "#{qualifier}ed_method" ).should ==
|
@@ -276,14 +276,14 @@ end
|
|
276
276
|
eval("#{qualifier}_spec").call( @instance )
|
277
277
|
end
|
278
278
|
|
279
|
-
|
279
|
+
it "should run in the sequence of definition within the same layer" do
|
280
280
|
ContextR::with_layers "multiple_#{qualifier}s".to_sym do
|
281
281
|
@instance.contextualized_method.should == "contextualized_method"
|
282
282
|
end
|
283
283
|
eval("#{qualifier}_multiple_spec").call( @instance )
|
284
284
|
end
|
285
285
|
|
286
|
-
|
286
|
+
it "should be able to stop the execution with `break!`" do
|
287
287
|
ContextR::with_layers "break_in_#{qualifier}".to_sym, :other_layer do
|
288
288
|
@instance.contextualized_method.should == "contextualized_method"
|
289
289
|
end
|
@@ -291,4 +291,3 @@ end
|
|
291
291
|
end
|
292
292
|
end
|
293
293
|
end
|
294
|
-
|
@@ -1,19 +1,19 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe 'Each first level module' do
|
4
|
+
it 'should have the same name and namespace_free_name' do
|
5
5
|
Math.namespace_free_name.should == Math.name
|
6
6
|
Kernel.namespace_free_name.should == Kernel.name
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
it 'should have a namespace_free_name matching their constant' do
|
10
10
|
Kernel.namespace_free_name.should == Kernel.to_s
|
11
11
|
Kernel.namespace_free_name.should == "Kernel"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
describe 'Each sublevel module' do
|
16
|
+
before do
|
17
17
|
module ModuleTestA
|
18
18
|
module B
|
19
19
|
module C
|
@@ -22,14 +22,14 @@ context 'Each sublevel module' do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
it 'should have a namespace free namespace_free_name' do
|
26
26
|
ModuleTestA::B.namespace_free_name.should == "B"
|
27
27
|
ModuleTestA::B::C.namespace_free_name.should == "C"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
describe "Each module" do
|
32
|
+
it "should have a attr_accessor_with_default_setter" do
|
33
33
|
lambda do
|
34
34
|
class ClassSpecA
|
35
35
|
attr_accessor_with_default_setter :miau do
|
@@ -40,57 +40,59 @@ context "Each module" do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
describe "Each instance" do
|
44
|
+
before do
|
45
45
|
@instance = ClassSpecA.new
|
46
46
|
@instance2 = ClassSpecA.new
|
47
47
|
end
|
48
|
-
|
49
|
-
|
48
|
+
|
49
|
+
it "should provide a getter method" do
|
50
|
+
@instance.should respond_to( :miau )
|
50
51
|
end
|
51
|
-
|
52
|
-
|
52
|
+
|
53
|
+
it "should provide a setter method" do
|
54
|
+
@instance.should respond_to( :miau= )
|
53
55
|
end
|
54
56
|
|
55
57
|
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
+
describe "A getter method" do
|
60
|
+
before do
|
59
61
|
@getter = ClassSpecA.instance_method( :miau )
|
60
62
|
@instance = ClassSpecA.new
|
61
63
|
@instance2 = ClassSpecA.new
|
62
64
|
end
|
63
65
|
|
64
|
-
|
66
|
+
it "should not expect a parameter" do
|
65
67
|
@getter.arity.should == 0
|
66
68
|
end
|
67
69
|
|
68
|
-
|
70
|
+
it "should provide the default value" do
|
69
71
|
@instance.miau.should == Hash.new
|
70
72
|
end
|
71
73
|
|
72
|
-
|
74
|
+
it "should provide the default value also multiple times" do
|
73
75
|
@instance.miau.object_id.should == @instance.miau.object_id
|
74
76
|
end
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
+
it "should provide the different default values for different " +
|
79
|
+
"instances" do
|
78
80
|
@instance2.miau.object_id.should_not == @instance.miau.object_id
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
+
describe "A setter method" do
|
85
|
+
before do
|
84
86
|
@setter = ClassSpecA.instance_method( :miau= )
|
85
87
|
@instance = ClassSpecA.new
|
86
88
|
@instance2 = ClassSpecA.new
|
87
89
|
end
|
88
90
|
|
89
|
-
|
91
|
+
it "should not expect a parameter" do
|
90
92
|
@setter.arity.should == 1
|
91
93
|
end
|
92
94
|
|
93
|
-
|
95
|
+
it "should allow the setting of the corresonding instance variable" do
|
94
96
|
begin
|
95
97
|
@instance.miau = "blue"
|
96
98
|
end.should == "blue"
|
data/spec/core_ext/proc_spec.rb
CHANGED
@@ -9,39 +9,39 @@ class ProcSpecFoo
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
describe "A Proc" do
|
13
|
+
before do
|
14
14
|
@a = lambda do @a = true; "a" end
|
15
15
|
@b = lambda do @b = true; "b" end
|
16
16
|
@foo = ProcSpecFoo.new
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
@b.to_unbound_method( ProcSpecFoo ).
|
19
|
+
it "should convert itself to an unbound method" do
|
20
|
+
@b.to_unbound_method( ProcSpecFoo ).should be_a_kind_of( UnboundMethod )
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
it "which should be bindable to an instance of the specified class" do
|
24
24
|
lambda do
|
25
25
|
@b.to_unbound_method( ProcSpecFoo ).bind( @foo )
|
26
26
|
end.should_not raise_error
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
it "which should execute the proc in turn" do
|
30
30
|
@b.to_unbound_method( ProcSpecFoo ).bind( @foo ).call.should == "b"
|
31
31
|
@foo.instance_variable_get( :@b ).should == true
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
@b.
|
34
|
+
it "should respond to `+`" do
|
35
|
+
@b.should respond_to( :+ )
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
(@a + @b).
|
38
|
+
it "should build a joined block with `self.+( other_proc)`" do
|
39
|
+
(@a + @b).should be_a_kind_of( Proc )
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
describe "The result of `+` of two Procs" do
|
44
|
+
before do
|
45
45
|
@a = lambda do | arg |
|
46
46
|
arg || "a"
|
47
47
|
end
|
@@ -50,12 +50,12 @@ context "The result of `+` of two Procs" do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
it "should give the correct return value" do
|
54
54
|
(@a + @b).call( nil ).should == "b"
|
55
55
|
(@b + @a).call( nil ).should == "a"
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
it "should pass through given parameters" do
|
59
59
|
(@a + @b).call( 1 ).should == 1
|
60
60
|
end
|
61
61
|
end
|
data/website/index.html
CHANGED
@@ -33,7 +33,7 @@
|
|
33
33
|
<h1>Context-oriented Programming in Ruby</h1>
|
34
34
|
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/contextr"; return false'>
|
35
35
|
Get Version
|
36
|
-
<a href="http://rubyforge.org/projects/contextr" class="numbers">0.0.
|
36
|
+
<a href="http://rubyforge.org/projects/contextr" class="numbers">0.0.3</a>
|
37
37
|
</div>
|
38
38
|
<h1>→ ‘contextr’</h1>
|
39
39
|
|
@@ -160,7 +160,8 @@ Name: Gregor Schmidt; Address: Berlin
|
|
160
160
|
|
161
161
|
|
162
162
|
<ul>
|
163
|
-
<li><a href="http://rubyforge.org/
|
163
|
+
<li><a href="http://contextr.rubyforge.org/contextr">ContextR <span class="caps">API</span> documentation</a></li>
|
164
|
+
<li><a href="http://rubyforge.org/projects/contextr">RubyForge Project Page</a></li>
|
164
165
|
<li><a href="http://www.nach-vorne.de">Author’s Development Blog – The Ruby Ahead</a></li>
|
165
166
|
<li><a href="http://www.ohloh.net/projects/5037">ContextR Statistics on ohloh</a></li>
|
166
167
|
</ul>
|
@@ -177,12 +178,17 @@ Name: Gregor Schmidt; Address: Berlin
|
|
177
178
|
|
178
179
|
<p>Comments are welcome. Send an email to <a href="mailto:ruby@schmidtwisser.de">Gregor Schmidt</a></p>
|
179
180
|
<p class="coda">
|
180
|
-
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>,
|
181
|
+
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 10th May 2007<br>
|
181
182
|
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
182
183
|
</p>
|
183
184
|
</div>
|
184
185
|
|
185
|
-
|
186
|
+
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
187
|
+
</script>
|
188
|
+
<script type="text/javascript">
|
189
|
+
_uacct = "UA-510991-4";
|
190
|
+
urchinTracker();
|
191
|
+
</script>
|
186
192
|
|
187
193
|
</body>
|
188
194
|
</html>
|
data/website/index.txt
CHANGED
@@ -115,7 +115,8 @@ You may find other examples in the <code>examples</code> folder.
|
|
115
115
|
|
116
116
|
h2. Other resources
|
117
117
|
|
118
|
-
* "
|
118
|
+
* "ContextR API documentation":http://contextr.rubyforge.org/contextr
|
119
|
+
* "RubyForge Project Page":http://rubyforge.org/projects/contextr
|
119
120
|
* "Author's Development Blog - The Ruby Ahead":http://www.nach-vorne.de
|
120
121
|
* "ContextR Statistics on ohloh":http://www.ohloh.net/projects/5037
|
121
122
|
|
data/website/template.rhtml
CHANGED
@@ -42,7 +42,12 @@
|
|
42
42
|
</p>
|
43
43
|
</div>
|
44
44
|
|
45
|
-
|
45
|
+
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
46
|
+
</script>
|
47
|
+
<script type="text/javascript">
|
48
|
+
_uacct = "UA-510991-4";
|
49
|
+
urchinTracker();
|
50
|
+
</script>
|
46
51
|
|
47
52
|
</body>
|
48
53
|
</html>
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.3
|
3
3
|
specification_version: 1
|
4
4
|
name: contextr
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-05-
|
6
|
+
version: 0.0.3
|
7
|
+
date: 2007-05-22 00:00:00 +02:00
|
8
8
|
summary: The goal is to equip Ruby with an API to allow context-oriented programming.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- Rakefile
|
38
38
|
- examples/education.rb
|
39
39
|
- examples/fibonacci.rb
|
40
|
+
- examples/with_current_context.rb
|
40
41
|
- lib/contextr.rb
|
41
42
|
- lib/contextr/contextr.rb
|
42
43
|
- lib/contextr/layer.rb
|
@@ -51,6 +52,7 @@ files:
|
|
51
52
|
- scripts/txt2html
|
52
53
|
- setup.rb
|
53
54
|
- spec/contextr/contextr_api_spec.rb
|
55
|
+
- spec/contextr/contextr_class_side_spec.rb
|
54
56
|
- spec/contextr/contextr_functional_spec.rb
|
55
57
|
- spec/core_ext/module_spec.rb
|
56
58
|
- spec/core_ext/proc_spec.rb
|
@@ -66,10 +68,16 @@ files:
|
|
66
68
|
test_files:
|
67
69
|
- test/contextr/test_contextr.rb
|
68
70
|
- test/test_helper.rb
|
69
|
-
rdoc_options:
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
rdoc_options:
|
72
|
+
- --main
|
73
|
+
- README.txt
|
74
|
+
extra_rdoc_files:
|
75
|
+
- COPYING.txt
|
76
|
+
- History.txt
|
77
|
+
- LICENSE.txt
|
78
|
+
- Manifest.txt
|
79
|
+
- README.txt
|
80
|
+
- website/index.txt
|
73
81
|
executables: []
|
74
82
|
|
75
83
|
extensions: []
|