contextr 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|