contextr 0.0.3 → 0.1.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.txt +5 -18
- data/License.txt +20 -0
- data/Manifest.txt +15 -19
- data/README.txt +2 -49
- data/Rakefile +55 -88
- data/examples/general.rb +152 -0
- data/examples/ordering.rb +29 -0
- data/lib/contextr.rb +15 -15
- data/lib/contextr/class_methods.rb +90 -0
- data/lib/contextr/core_ext.rb +2 -0
- data/lib/contextr/core_ext/module.rb +18 -0
- data/lib/contextr/core_ext/object.rb +9 -0
- data/lib/contextr/event_machine.rb +71 -0
- data/lib/contextr/layer.rb +57 -381
- data/lib/contextr/modules/mutex_code.rb +22 -0
- data/lib/contextr/modules/unique_id.rb +13 -0
- data/lib/contextr/public_api.rb +58 -0
- data/lib/contextr/version.rb +2 -2
- data/lib/ext/active_support_subset.rb +85 -0
- data/spec/contextr_spec.rb +11 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +1 -1
- data/test/test_contextr.rb +11 -0
- data/website/index.html +23 -101
- data/website/index.txt +27 -95
- data/website/stylesheets/screen.css +9 -0
- data/website/template.rhtml +3 -8
- metadata +21 -26
- data/COPYING.txt +0 -340
- data/LICENSE.txt +0 -57
- data/examples/education.rb +0 -71
- data/examples/fibonacci.rb +0 -124
- data/examples/with_current_context.rb +0 -29
- data/lib/contextr/contextr.rb +0 -160
- data/lib/core_ext/class.rb +0 -29
- data/lib/core_ext/module.rb +0 -62
- data/lib/core_ext/proc.rb +0 -53
- data/lib/ext/method_nature.rb +0 -80
- data/rake/group_spec_task.rb +0 -7
- data/rake/specific_group_spec_task.rb +0 -7
- data/spec/contextr/contextr_api_spec.rb +0 -126
- data/spec/contextr/contextr_class_side_spec.rb +0 -77
- data/spec/contextr/contextr_functional_spec.rb +0 -293
- data/spec/core_ext/module_spec.rb +0 -101
- data/spec/core_ext/proc_spec.rb +0 -61
- data/tasks/annotations.rb +0 -107
- data/test/contextr/test_contextr.rb +0 -7
@@ -0,0 +1,22 @@
|
|
1
|
+
require "thread"
|
2
|
+
module MutexCode
|
3
|
+
def semaphore
|
4
|
+
@semaphore ||= Mutex.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def synchronized
|
8
|
+
semaphore.synchronize do
|
9
|
+
yield
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_blocked?
|
14
|
+
semaphore.locked?
|
15
|
+
end
|
16
|
+
|
17
|
+
def only_once
|
18
|
+
synchronized do
|
19
|
+
yield
|
20
|
+
end unless is_blocked?
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ContextR
|
2
|
+
module ClassMethods
|
3
|
+
include MutexCode
|
4
|
+
|
5
|
+
# allows the explicit activation of layers within a block context
|
6
|
+
#
|
7
|
+
# ContextR::with_layers(:foo, :bar) do
|
8
|
+
# ContextR::current_layers # => [:default, :foo, :bar]
|
9
|
+
#
|
10
|
+
# ContextR::with_layers(:baz) do
|
11
|
+
# ContextR::current_layers # => [:default, :foo, :bar, :baz]
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# :call-seq:
|
17
|
+
# with_layers(layer_name, ...) { ... }
|
18
|
+
#
|
19
|
+
def with_layers(*layer_symbols, &block)
|
20
|
+
layers = layer_symbols.collect do | layer_symbol |
|
21
|
+
layer_by_symbol(layer_symbol)
|
22
|
+
end
|
23
|
+
Dynamic.let({ :layers => Dynamic[:layers] | layers }, &block)
|
24
|
+
end
|
25
|
+
alias with_layer with_layers
|
26
|
+
|
27
|
+
# allows the explicit deactivation of layers within a block context
|
28
|
+
#
|
29
|
+
# ContextR::with_layers(:foo, :bar) do
|
30
|
+
# ContextR::current_layers # => [:default, :foo, :bar]
|
31
|
+
#
|
32
|
+
# ContextR::without_layers(:foo) do
|
33
|
+
# ContextR::current_layers # => [:default, :bar]
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# :call-seq:
|
39
|
+
# without_layers(layer_name, ...) { ... }
|
40
|
+
#
|
41
|
+
def without_layers(*layer_symbols, &block)
|
42
|
+
layers = layer_symbols.collect do | layer_symbol |
|
43
|
+
layer_by_symbol(layer_symbol)
|
44
|
+
end
|
45
|
+
Dynamic.let({ :layers => Dynamic[:layers] - layers }, &block)
|
46
|
+
end
|
47
|
+
alias without_layer without_layers
|
48
|
+
|
49
|
+
def layers
|
50
|
+
Dynamic[:layers]
|
51
|
+
end
|
52
|
+
|
53
|
+
def layer_symbols
|
54
|
+
layers.collect { | layer | symbol_by_layer(layer) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/lib/contextr/version.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
unless Object.const_defined? "ActiveSupport"
|
2
|
+
class Module
|
3
|
+
def alias_method_chain(target, feature)
|
4
|
+
# Strip out punctuation on predicates or bang methods since
|
5
|
+
# e.g. target?_without_feature is not a valid method name.
|
6
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
7
|
+
yield(aliased_target, punctuation) if block_given?
|
8
|
+
|
9
|
+
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
10
|
+
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
11
|
+
|
12
|
+
alias_method without_method, target
|
13
|
+
alias_method target, with_method
|
14
|
+
|
15
|
+
case
|
16
|
+
when public_method_defined?(without_method)
|
17
|
+
public target
|
18
|
+
when protected_method_defined?(without_method)
|
19
|
+
protected target
|
20
|
+
when private_method_defined?(without_method)
|
21
|
+
private target
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Inflector
|
27
|
+
extend self
|
28
|
+
|
29
|
+
def camelize(lower_case_and_underscored_word,
|
30
|
+
first_letter_in_uppercase = true)
|
31
|
+
if first_letter_in_uppercase
|
32
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) {
|
33
|
+
"::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
34
|
+
else
|
35
|
+
lower_case_and_underscored_word.first +
|
36
|
+
camelize(lower_case_and_underscored_word)[1..-1]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def underscore(camel_cased_word)
|
41
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
42
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
43
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
44
|
+
tr("-", "_").
|
45
|
+
downcase
|
46
|
+
end
|
47
|
+
|
48
|
+
def constantize(camel_cased_word)
|
49
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
50
|
+
raise NameError,
|
51
|
+
"#{camel_cased_word.inspect} is not a valid constant name!"
|
52
|
+
end
|
53
|
+
|
54
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module ActiveSupport
|
59
|
+
module CoreExtensions
|
60
|
+
module String
|
61
|
+
module Inflections
|
62
|
+
def camelize(first_letter = :upper)
|
63
|
+
case first_letter
|
64
|
+
when :upper then Inflector.camelize(self, true)
|
65
|
+
when :lower then Inflector.camelize(self, false)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias_method :camelcase, :camelize
|
69
|
+
|
70
|
+
def underscore
|
71
|
+
Inflector.underscore(self)
|
72
|
+
end
|
73
|
+
|
74
|
+
def constantize
|
75
|
+
Inflector.constantize(self)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class String
|
83
|
+
include ActiveSupport::CoreExtensions::String::Inflections
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'spec'
|
data/website/index.html
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
7
|
<title>
|
8
|
-
|
8
|
+
contextr
|
9
9
|
</title>
|
10
10
|
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
11
|
<style>
|
@@ -30,10 +30,10 @@
|
|
30
30
|
<body>
|
31
31
|
<div id="main">
|
32
32
|
|
33
|
-
<h1>
|
33
|
+
<h1>contextr</h1>
|
34
34
|
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/contextr"; return false'>
|
35
|
-
Get Version
|
36
|
-
<a href="http://rubyforge.org/projects/contextr" class="numbers">0.0.
|
35
|
+
<p>Get Version</p>
|
36
|
+
<a href="http://rubyforge.org/projects/contextr" class="numbers">0.0.9</a>
|
37
37
|
</div>
|
38
38
|
<h1>→ ‘contextr’</h1>
|
39
39
|
|
@@ -47,9 +47,6 @@
|
|
47
47
|
<h2>Installing</h2>
|
48
48
|
|
49
49
|
|
50
|
-
<p>Nothing more than typing</p>
|
51
|
-
|
52
|
-
|
53
50
|
<pre syntax="ruby">sudo gem install contextr</pre>
|
54
51
|
|
55
52
|
<h2>The basics</h2>
|
@@ -58,7 +55,7 @@
|
|
58
55
|
<p>In your code use</p>
|
59
56
|
|
60
57
|
|
61
|
-
<pre syntax="ruby">require 'rubygems'
|
58
|
+
<pre syntax="ruby">require 'rubygems'
|
62
59
|
require 'contextr'</pre>
|
63
60
|
|
64
61
|
<p>and ContextR will be ready to use.</p>
|
@@ -67,93 +64,13 @@ require 'contextr'</pre>
|
|
67
64
|
<h2>Demonstration of usage</h2>
|
68
65
|
|
69
66
|
|
70
|
-
<
|
71
|
-
require "rubygems"
|
72
|
-
require "contextr"
|
73
|
-
|
74
|
-
class Person
|
75
|
-
attr_accessor :name, :address, :university
|
76
|
-
|
77
|
-
def initialize name, address, university
|
78
|
-
self.name = name
|
79
|
-
self.address = address
|
80
|
-
self.university = university
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_s
|
84
|
-
"Name: #{name}"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class University
|
89
|
-
attr_accessor :name, :address
|
90
|
-
|
91
|
-
def initialize name, address
|
92
|
-
self.name = name
|
93
|
-
self.address = address
|
94
|
-
end
|
95
|
-
|
96
|
-
def to_s
|
97
|
-
"Name: #{name}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
class Person
|
102
|
-
layer :address, :education
|
103
|
-
|
104
|
-
address.post :to_s do | n |
|
105
|
-
n.return_value += "; Address: #{address}"
|
106
|
-
end
|
107
|
-
|
108
|
-
education.post :to_s do | n |
|
109
|
-
n.return_value += ";\n[Education] #{university}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
class University
|
114
|
-
layer :address
|
67
|
+
<p>Please see the examples/ folder in the source distribution for example uses</p>
|
115
68
|
|
116
|
-
address.post :to_s do | n |
|
117
|
-
n.return_value += "; Address: #{address}"
|
118
|
-
end
|
119
|
-
end
|
120
69
|
|
121
|
-
|
122
|
-
somePerson = Person.new( "Gregor Schmidt", "Berlin", hpi )
|
70
|
+
<h2>Forum</h2>
|
123
71
|
|
124
|
-
puts
|
125
|
-
puts somePerson
|
126
|
-
ContextR::with_layers :education do
|
127
|
-
puts
|
128
|
-
puts somePerson
|
129
72
|
|
130
|
-
|
131
|
-
puts
|
132
|
-
puts somePerson
|
133
|
-
|
134
|
-
ContextR::without_layers :education do
|
135
|
-
puts
|
136
|
-
puts somePerson
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
puts
|
141
|
-
</pre>
|
142
|
-
The above code prints:
|
143
|
-
|
144
|
-
<pre>
|
145
|
-
Name: Gregor Schmidt
|
146
|
-
|
147
|
-
Name: Gregor Schmidt;
|
148
|
-
[Education] Name: Hasso-Plattner-Institut
|
149
|
-
|
150
|
-
Name: Gregor Schmidt; Address: Berlin;
|
151
|
-
[Education] Name: Hasso-Plattner-Institut; Address: Potsdam
|
152
|
-
|
153
|
-
Name: Gregor Schmidt; Address: Berlin
|
154
|
-
</pre>
|
155
|
-
|
156
|
-
<p>You may find other examples in the <code>examples</code> folder.</p>
|
73
|
+
<p><a href="http://groups.google.com/group/contextr">http://groups.google.com/group/contextr</a></p>
|
157
74
|
|
158
75
|
|
159
76
|
<h2>Other resources</h2>
|
@@ -162,33 +79,38 @@ Name: Gregor Schmidt; Address: Berlin
|
|
162
79
|
<ul>
|
163
80
|
<li><a href="http://contextr.rubyforge.org/contextr">ContextR <span class="caps">API</span> documentation</a></li>
|
164
81
|
<li><a href="http://rubyforge.org/projects/contextr">RubyForge Project Page</a></li>
|
165
|
-
<li><a href="http://www.
|
82
|
+
<li><a href="http://www.swa.hpi.uni-potsdam.de/cop/"><span class="caps">COP</span> at <span class="caps">SWA</span> at the <span class="caps">HPI</span></a> More information on other context-oriented programming libaries as well as papers and theoretical work can be found at the <span class="caps">COP</span> page of Prof. Hirschfeld’s software architecture group at the <span class="caps">HPI</span></li>
|
83
|
+
<li><a href="http://www.nach-vorne.de">Author‘s Development Blog – The Ruby Ahead</a></li>
|
166
84
|
<li><a href="http://www.ohloh.net/projects/5037">ContextR Statistics on ohloh</a></li>
|
167
85
|
</ul>
|
168
86
|
|
169
87
|
|
88
|
+
<h2>How to submit patches</h2>
|
89
|
+
|
90
|
+
|
91
|
+
<p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people’s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
|
92
|
+
|
93
|
+
|
94
|
+
<p>The trunk repository is <code>http://contextr.rubyforge.org/svn/trunk/</code> for anonymous access.</p>
|
95
|
+
|
96
|
+
|
170
97
|
<h2>License</h2>
|
171
98
|
|
172
99
|
|
173
|
-
<p>This code is free to use under the
|
100
|
+
<p>This code is free to use under the terms of the <a href="http://www.ruby-lang.org/en/LICENSE.txt">Ruby license</a>.</p>
|
174
101
|
|
175
102
|
|
176
103
|
<h2>Contact</h2>
|
177
104
|
|
178
105
|
|
179
|
-
<p>Comments are welcome. Send an email to <a href="mailto:ruby@schmidtwisser.de">Gregor Schmidt</a
|
106
|
+
<p>Comments are welcome. Send an email to <a href="mailto:ruby@schmidtwisser.de">Gregor Schmidt</a>.</p>
|
180
107
|
<p class="coda">
|
181
|
-
|
108
|
+
7th September 2007<br>
|
182
109
|
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
183
110
|
</p>
|
184
111
|
</div>
|
185
112
|
|
186
|
-
|
187
|
-
</script>
|
188
|
-
<script type="text/javascript">
|
189
|
-
_uacct = "UA-510991-4";
|
190
|
-
urchinTracker();
|
191
|
-
</script>
|
113
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
192
114
|
|
193
115
|
</body>
|
194
116
|
</html>
|
data/website/index.txt
CHANGED
@@ -1,129 +1,61 @@
|
|
1
|
-
h1.
|
1
|
+
h1. contextr
|
2
2
|
|
3
3
|
h1. → 'contextr'
|
4
4
|
|
5
5
|
|
6
6
|
h2. What
|
7
7
|
|
8
|
-
|
8
|
+
This is the first release of ContextR after the 0.0.3 release. Since then a
|
9
|
+
full redesign took place. The API changed entirely so make sure to not use
|
10
|
+
this release with older code.
|
9
11
|
|
10
|
-
|
12
|
+
We think, that the new API is more powerful and allows better code to be written
|
13
|
+
with ContextR. Unfortunately it has some issues as well, but we consider them
|
14
|
+
as less relevant than the other way around. If you have any problems or question
|
15
|
+
concerning these changes, feel free to use the new
|
16
|
+
"mailing list":http://groups.google.com/group/contextr - any hint is appreciated
|
11
17
|
|
12
|
-
|
18
|
+
h2. Installing
|
13
19
|
|
14
20
|
<pre syntax="ruby">sudo gem install contextr</pre>
|
15
21
|
|
16
22
|
h2. The basics
|
17
23
|
|
18
|
-
In your code use
|
24
|
+
In your code use
|
19
25
|
|
20
|
-
<pre syntax="ruby">require 'rubygems'
|
26
|
+
<pre syntax="ruby">require 'rubygems'
|
21
27
|
require 'contextr'</pre>
|
22
28
|
|
23
29
|
and ContextR will be ready to use.
|
24
30
|
|
25
|
-
h2. Demonstration of usage
|
26
|
-
|
27
|
-
<pre syntax="ruby">
|
28
|
-
require "rubygems"
|
29
|
-
require "contextr"
|
30
|
-
|
31
|
-
class Person
|
32
|
-
attr_accessor :name, :address, :university
|
33
|
-
|
34
|
-
def initialize name, address, university
|
35
|
-
self.name = name
|
36
|
-
self.address = address
|
37
|
-
self.university = university
|
38
|
-
end
|
39
|
-
|
40
|
-
def to_s
|
41
|
-
"Name: #{name}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class University
|
46
|
-
attr_accessor :name, :address
|
47
|
-
|
48
|
-
def initialize name, address
|
49
|
-
self.name = name
|
50
|
-
self.address = address
|
51
|
-
end
|
52
|
-
|
53
|
-
def to_s
|
54
|
-
"Name: #{name}"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
class Person
|
59
|
-
layer :address, :education
|
60
|
-
|
61
|
-
address.post :to_s do | n |
|
62
|
-
n.return_value += "; Address: #{address}"
|
63
|
-
end
|
64
31
|
|
65
|
-
|
66
|
-
n.return_value += ";\n[Education] #{university}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
class University
|
71
|
-
layer :address
|
72
|
-
|
73
|
-
address.post :to_s do | n |
|
74
|
-
n.return_value += "; Address: #{address}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
hpi = University.new( "Hasso-Plattner-Institut", "Potsdam" )
|
80
|
-
somePerson = Person.new( "Gregor Schmidt", "Berlin", hpi )
|
81
|
-
|
82
|
-
puts
|
83
|
-
puts somePerson
|
84
|
-
ContextR::with_layers :education do
|
85
|
-
puts
|
86
|
-
puts somePerson
|
32
|
+
h2. Demonstration of usage
|
87
33
|
|
88
|
-
|
89
|
-
puts
|
90
|
-
puts somePerson
|
34
|
+
Please see the examples/ folder in the source distribution for example uses
|
91
35
|
|
92
|
-
|
93
|
-
puts
|
94
|
-
puts somePerson
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
puts
|
99
|
-
</pre>
|
100
|
-
The above code prints:
|
36
|
+
h2. Forum
|
101
37
|
|
102
|
-
|
103
|
-
Name: Gregor Schmidt
|
38
|
+
"http://groups.google.com/group/contextr":http://groups.google.com/group/contextr
|
104
39
|
|
105
|
-
|
106
|
-
[Education] Name: Hasso-Plattner-Institut
|
40
|
+
h2. Other resources
|
107
41
|
|
108
|
-
|
109
|
-
|
42
|
+
* "ContextR API documentation":http://contextr.rubyforge.org/rdoc
|
43
|
+
* "RubyForge Project Page":http://rubyforge.org/projects/contextr
|
44
|
+
* "COP at SWA at the HPI":http://www.swa.hpi.uni-potsdam.de/cop/ More information on other context-oriented programming libaries as well as papers and theoretical work can be found at the COP page of Prof. Hirschfeld's software architecture group at the HPI
|
45
|
+
* "Author‘s Development Blog - The Ruby Ahead":http://www.nach-vorne.de
|
46
|
+
* "ContextR Statistics on ohloh":http://www.ohloh.net/projects/5037
|
110
47
|
|
111
|
-
Name: Gregor Schmidt; Address: Berlin
|
112
|
-
</pre>
|
113
48
|
|
114
|
-
|
49
|
+
h2. How to submit patches
|
115
50
|
|
116
|
-
|
51
|
+
Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
|
117
52
|
|
118
|
-
|
119
|
-
* "RubyForge Project Page":http://rubyforge.org/projects/contextr
|
120
|
-
* "Author's Development Blog - The Ruby Ahead":http://www.nach-vorne.de
|
121
|
-
* "ContextR Statistics on ohloh":http://www.ohloh.net/projects/5037
|
53
|
+
The trunk repository is <code>http://contextr.rubyforge.org/svn/trunk/</code> for anonymous access.
|
122
54
|
|
123
55
|
h2. License
|
124
56
|
|
125
|
-
This code is free to use under the
|
57
|
+
This code is free to use under the terms of the "Ruby license":http://www.ruby-lang.org/en/LICENSE.txt.
|
126
58
|
|
127
59
|
h2. Contact
|
128
60
|
|
129
|
-
Comments are welcome. Send an email to "Gregor Schmidt":mailto:ruby@schmidtwisser.de
|
61
|
+
Comments are welcome. Send an email to "Gregor Schmidt":mailto:ruby@schmidtwisser.de.
|