blockenspiel 0.2.0.1-java
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.rdoc +46 -0
- data/ImplementingDSLblocks.rdoc +934 -0
- data/README.rdoc +350 -0
- data/Rakefile +218 -0
- data/ext/blockenspiel/BlockenspielUnmixerService.java +140 -0
- data/ext/blockenspiel/extconf.rb +2 -0
- data/ext/blockenspiel/unmixer.c +86 -0
- data/lib/blockenspiel.rb +43 -0
- data/lib/blockenspiel/impl.rb +670 -0
- data/lib/blockenspiel/version.rb +42 -0
- data/lib/blockenspiel_unmixer.jar +0 -0
- data/tests/tc_basic.rb +137 -0
- data/tests/tc_behaviors.rb +191 -0
- data/tests/tc_dsl_methods.rb +324 -0
- data/tests/tc_dynamic.rb +175 -0
- data/tests/tc_mixins.rb +240 -0
- metadata +77 -0
data/tests/tc_dynamic.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Blockenspiel dynamic tests
|
4
|
+
#
|
5
|
+
# This file contains tests for dynamic DSL generation.
|
6
|
+
#
|
7
|
+
# -----------------------------------------------------------------------------
|
8
|
+
# Copyright 2008-2009 Daniel Azuma
|
9
|
+
#
|
10
|
+
# All rights reserved.
|
11
|
+
#
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
14
|
+
#
|
15
|
+
# * Redistributions of source code must retain the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer.
|
17
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
18
|
+
# this list of conditions and the following disclaimer in the documentation
|
19
|
+
# and/or other materials provided with the distribution.
|
20
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
21
|
+
# contributors to this software, may be used to endorse or promote products
|
22
|
+
# derived from this software without specific prior written permission.
|
23
|
+
#
|
24
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
25
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
26
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
27
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
28
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
29
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
30
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
31
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
32
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
33
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
34
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
# -----------------------------------------------------------------------------
|
36
|
+
;
|
37
|
+
|
38
|
+
|
39
|
+
require 'test/unit'
|
40
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../lib/blockenspiel.rb")
|
41
|
+
|
42
|
+
|
43
|
+
module Blockenspiel
|
44
|
+
module Tests # :nodoc:
|
45
|
+
|
46
|
+
class TestDynamic < Test::Unit::TestCase # :nodoc:
|
47
|
+
|
48
|
+
|
49
|
+
# Test the simple case.
|
50
|
+
#
|
51
|
+
# * Asserts that the simplest case works.
|
52
|
+
|
53
|
+
def test_simple
|
54
|
+
block_ = proc do
|
55
|
+
set_value(:a, 1)
|
56
|
+
end
|
57
|
+
hash_ = Hash.new
|
58
|
+
Blockenspiel.invoke(block_) do
|
59
|
+
add_method(:set_value) do |key_, value_|
|
60
|
+
hash_[key_] = value_
|
61
|
+
end
|
62
|
+
end
|
63
|
+
assert_equal(1, hash_[:a])
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Test renaming.
|
68
|
+
#
|
69
|
+
# * Asserts that the method appears renamed in a parameterless block.
|
70
|
+
# * Asserts that the method appears in its original name in a parametered block.
|
71
|
+
|
72
|
+
def test_renaming
|
73
|
+
hash_ = Hash.new
|
74
|
+
dsl_definition_ = proc do
|
75
|
+
add_method(:set_value, :dsl_method => :renamed_set_value) do |key_, value_|
|
76
|
+
hash_[key_] = value_
|
77
|
+
end
|
78
|
+
end
|
79
|
+
block1_ = proc do
|
80
|
+
renamed_set_value(:a, 1)
|
81
|
+
assert_raise(NoMethodError){ set_value(:b, 2) }
|
82
|
+
end
|
83
|
+
Blockenspiel.invoke(block1_, &dsl_definition_)
|
84
|
+
block2_ = proc do |dsl_|
|
85
|
+
dsl_.set_value(:c, 3)
|
86
|
+
assert_raise(NoMethodError){ renamed_set_value(:d, 4) }
|
87
|
+
end
|
88
|
+
Blockenspiel.invoke(block2_, &dsl_definition_)
|
89
|
+
assert_equal(1, hash_[:a])
|
90
|
+
assert_nil(hash_[:b])
|
91
|
+
assert_equal(3, hash_[:c])
|
92
|
+
assert_nil(hash_[:d])
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Test calls with blocks.
|
97
|
+
#
|
98
|
+
# * Asserts that a block passed "first" works.
|
99
|
+
# * Asserts that a block passed "last" works.
|
100
|
+
# * Asserts that a block passed "last" works.
|
101
|
+
|
102
|
+
def test_blocks_first_and_last
|
103
|
+
hash_ = Hash.new
|
104
|
+
dsl_definition_ = proc do
|
105
|
+
add_method(:set_value1, :block => :first) do |bl_, key_|
|
106
|
+
hash_[key_] = bl_.call
|
107
|
+
end
|
108
|
+
add_method(:set_value2, :block => :last) do |key_, bl_|
|
109
|
+
hash_[key_] = bl_.call
|
110
|
+
end
|
111
|
+
add_method(:set_value3, :block => true) do |bl_, key_|
|
112
|
+
hash_[key_] = bl_.call
|
113
|
+
end
|
114
|
+
end
|
115
|
+
block_ = proc do
|
116
|
+
set_value1(:a){ 1 }
|
117
|
+
set_value2(:b){ 2 }
|
118
|
+
set_value2(:c){ 3 }
|
119
|
+
end
|
120
|
+
Blockenspiel.invoke(block_, &dsl_definition_)
|
121
|
+
assert_equal(1, hash_[:a])
|
122
|
+
assert_equal(2, hash_[:b])
|
123
|
+
assert_equal(3, hash_[:c])
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Test calls with blocks not passed.
|
128
|
+
#
|
129
|
+
# * Asserts that if a block isn't given, it is set to nil.
|
130
|
+
|
131
|
+
def test_blocks_nil
|
132
|
+
hash_ = Hash.new
|
133
|
+
dsl_definition_ = proc do
|
134
|
+
add_method(:set_value1, :block => :first) do |bl_, key_|
|
135
|
+
assert_nil(bl_)
|
136
|
+
end
|
137
|
+
add_method(:set_value2, :block => :last) do |key_, bl_|
|
138
|
+
assert_nil(bl_)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
block_ = proc do
|
142
|
+
set_value1(:a)
|
143
|
+
set_value2(:b)
|
144
|
+
end
|
145
|
+
Blockenspiel.invoke(block_, &dsl_definition_)
|
146
|
+
assert_nil(hash_[:a])
|
147
|
+
assert_nil(hash_[:b])
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# Test calls with blocks (legacy api)
|
152
|
+
#
|
153
|
+
# * Asserts that a block passed "first" works.
|
154
|
+
# * Asserts that a block passed "last" works.
|
155
|
+
# * Asserts that a block passed "last" works.
|
156
|
+
|
157
|
+
def test_blocks_legacy
|
158
|
+
hash_ = Hash.new
|
159
|
+
dsl_definition_ = proc do
|
160
|
+
add_method(:set_value, :receive_block => true) do |key_, bl_|
|
161
|
+
hash_[key_] = bl_.call
|
162
|
+
end
|
163
|
+
end
|
164
|
+
block_ = proc do
|
165
|
+
set_value(:a){ 1 }
|
166
|
+
end
|
167
|
+
Blockenspiel.invoke(block_, &dsl_definition_)
|
168
|
+
assert_equal(1, hash_[:a])
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
data/tests/tc_mixins.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Blockenspiel mixin tests
|
4
|
+
#
|
5
|
+
# This file contains tests for various mixin cases,
|
6
|
+
# including nested blocks and multithreading.
|
7
|
+
#
|
8
|
+
# -----------------------------------------------------------------------------
|
9
|
+
# Copyright 2008-2009 Daniel Azuma
|
10
|
+
#
|
11
|
+
# All rights reserved.
|
12
|
+
#
|
13
|
+
# Redistribution and use in source and binary forms, with or without
|
14
|
+
# modification, are permitted provided that the following conditions are met:
|
15
|
+
#
|
16
|
+
# * Redistributions of source code must retain the above copyright notice,
|
17
|
+
# this list of conditions and the following disclaimer.
|
18
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
19
|
+
# this list of conditions and the following disclaimer in the documentation
|
20
|
+
# and/or other materials provided with the distribution.
|
21
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
22
|
+
# contributors to this software, may be used to endorse or promote products
|
23
|
+
# derived from this software without specific prior written permission.
|
24
|
+
#
|
25
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
26
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
27
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
28
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
29
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
30
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
31
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
32
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
33
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
34
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
35
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
36
|
+
# -----------------------------------------------------------------------------
|
37
|
+
;
|
38
|
+
|
39
|
+
|
40
|
+
require 'test/unit'
|
41
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../lib/blockenspiel.rb")
|
42
|
+
|
43
|
+
|
44
|
+
module Blockenspiel
|
45
|
+
module Tests # :nodoc:
|
46
|
+
|
47
|
+
class TestMixins < Test::Unit::TestCase # :nodoc:
|
48
|
+
|
49
|
+
|
50
|
+
class Target1 < Blockenspiel::Base
|
51
|
+
|
52
|
+
def initialize(hash_)
|
53
|
+
@hash = hash_
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_value(key_, value_)
|
57
|
+
@hash["#{key_}1"] = value_
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_value2(key_)
|
61
|
+
@hash["#{key_}1"] = yield
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
class Target2 < Blockenspiel::Base
|
68
|
+
|
69
|
+
dsl_methods false
|
70
|
+
|
71
|
+
def initialize(hash_=nil)
|
72
|
+
@hash = hash_ || Hash.new
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_value(key_, value_)
|
76
|
+
@hash["#{key_}2"] = value_
|
77
|
+
end
|
78
|
+
dsl_method :set_value
|
79
|
+
|
80
|
+
def set_value2(key_)
|
81
|
+
@hash["#{key_}2"] = yield
|
82
|
+
end
|
83
|
+
dsl_method :set_value2_inmixin, :set_value2
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# Basic test of mixin mechanism.
|
89
|
+
#
|
90
|
+
# * Asserts that the mixin methods are added and removed for a single mixin.
|
91
|
+
# * Asserts that the methods properly delegate to the target object.
|
92
|
+
# * Asserts that self doesn't change, and instance variables are preserved.
|
93
|
+
|
94
|
+
def test_basic_mixin
|
95
|
+
hash_ = Hash.new
|
96
|
+
saved_object_id_ = self.object_id
|
97
|
+
@my_instance_variable_test = :hello
|
98
|
+
assert(!self.respond_to?(:set_value))
|
99
|
+
assert(!self.respond_to?(:set_value2))
|
100
|
+
block_ = proc do
|
101
|
+
set_value('a', 1)
|
102
|
+
set_value2('b'){ 2 }
|
103
|
+
assert_equal(:hello, @my_instance_variable_test)
|
104
|
+
assert_equal(saved_object_id_, self.object_id)
|
105
|
+
end
|
106
|
+
Blockenspiel.invoke(block_, Target1.new(hash_))
|
107
|
+
assert(!self.respond_to?(:set_value))
|
108
|
+
assert(!self.respond_to?(:set_value2))
|
109
|
+
assert_equal(1, hash_['a1'])
|
110
|
+
assert_equal(2, hash_['b1'])
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# Test renaming of mixin methods.
|
115
|
+
#
|
116
|
+
# * Asserts that correctly renamed mixin methods are added and removed.
|
117
|
+
# * Asserts that the methods properly delegate to the target object.
|
118
|
+
|
119
|
+
def test_mixin_with_renaming
|
120
|
+
hash_ = Hash.new
|
121
|
+
assert(!self.respond_to?(:set_value))
|
122
|
+
assert(!self.respond_to?(:set_value2))
|
123
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
124
|
+
block_ = proc do
|
125
|
+
set_value('a', 1)
|
126
|
+
set_value2_inmixin('b'){ 2 }
|
127
|
+
assert(!self.respond_to?(:set_value2))
|
128
|
+
end
|
129
|
+
Blockenspiel.invoke(block_, Target2.new(hash_))
|
130
|
+
assert(!self.respond_to?(:set_value))
|
131
|
+
assert(!self.respond_to?(:set_value2))
|
132
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
133
|
+
assert_equal(1, hash_['a2'])
|
134
|
+
assert_equal(2, hash_['b2'])
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
# Test of two different nested mixins.
|
139
|
+
#
|
140
|
+
# * Asserts that the right methods are added and removed at the right time.
|
141
|
+
# * Asserts that the methods delegate to the right target object, even when
|
142
|
+
# multiple mixins add the same method name
|
143
|
+
|
144
|
+
def test_nested_different
|
145
|
+
hash_ = Hash.new
|
146
|
+
assert(!self.respond_to?(:set_value))
|
147
|
+
assert(!self.respond_to?(:set_value2))
|
148
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
149
|
+
Blockenspiel.invoke(proc do
|
150
|
+
set_value('a', 1)
|
151
|
+
set_value2('b'){ 2 }
|
152
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
153
|
+
Blockenspiel.invoke(proc do
|
154
|
+
set_value('c', 1)
|
155
|
+
set_value2_inmixin('d'){ 2 }
|
156
|
+
end, Target2.new(hash_))
|
157
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
158
|
+
set_value('e', 1)
|
159
|
+
set_value2('f'){ 2 }
|
160
|
+
end, Target1.new(hash_))
|
161
|
+
assert(!self.respond_to?(:set_value))
|
162
|
+
assert(!self.respond_to?(:set_value2))
|
163
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
164
|
+
assert_equal(1, hash_['a1'])
|
165
|
+
assert_equal(2, hash_['b1'])
|
166
|
+
assert_equal(1, hash_['c2'])
|
167
|
+
assert_equal(2, hash_['d2'])
|
168
|
+
assert_equal(1, hash_['e1'])
|
169
|
+
assert_equal(2, hash_['f1'])
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
# Test of the same mixin nested in itself.
|
174
|
+
#
|
175
|
+
# * Asserts that the methods are added and removed at the right time.
|
176
|
+
|
177
|
+
def test_nested_same
|
178
|
+
hash_ = Hash.new
|
179
|
+
assert(!self.respond_to?(:set_value))
|
180
|
+
assert(!self.respond_to?(:set_value2))
|
181
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
182
|
+
Blockenspiel.invoke(proc do
|
183
|
+
set_value('a', 1)
|
184
|
+
set_value2_inmixin('b'){ 2 }
|
185
|
+
Blockenspiel.invoke(proc do
|
186
|
+
set_value('c', 1)
|
187
|
+
set_value2_inmixin('d'){ 2 }
|
188
|
+
assert(!self.respond_to?(:set_value2))
|
189
|
+
end, Target2.new(hash_))
|
190
|
+
set_value('e', 1)
|
191
|
+
set_value2_inmixin('f'){ 2 }
|
192
|
+
end, Target2.new(hash_))
|
193
|
+
assert(!self.respond_to?(:set_value))
|
194
|
+
assert(!self.respond_to?(:set_value2))
|
195
|
+
assert(!self.respond_to?(:set_value2_inmixin))
|
196
|
+
assert_equal(1, hash_['a2'])
|
197
|
+
assert_equal(2, hash_['b2'])
|
198
|
+
assert_equal(1, hash_['c2'])
|
199
|
+
assert_equal(2, hash_['d2'])
|
200
|
+
assert_equal(1, hash_['e2'])
|
201
|
+
assert_equal(2, hash_['f2'])
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
# Test of two threads mixing the same mixin into the same object
|
206
|
+
#
|
207
|
+
# * Asserts that the mixin is removed only after the second thread is done.
|
208
|
+
|
209
|
+
def test_threads_same_mixin
|
210
|
+
hash_ = Hash.new
|
211
|
+
block1_ = proc do
|
212
|
+
set_value('a', 1)
|
213
|
+
sleep(0.5)
|
214
|
+
set_value2('b'){ 2 }
|
215
|
+
end
|
216
|
+
block2_ = proc do
|
217
|
+
set_value('c', 3)
|
218
|
+
sleep(1)
|
219
|
+
set_value2('d'){ 4 }
|
220
|
+
end
|
221
|
+
target_ = Target1.new(hash_)
|
222
|
+
thread1_ = Thread.new do
|
223
|
+
Blockenspiel.invoke(block1_, target_)
|
224
|
+
end
|
225
|
+
thread2_ = Thread.new do
|
226
|
+
Blockenspiel.invoke(block2_, target_)
|
227
|
+
end
|
228
|
+
thread1_.join
|
229
|
+
thread2_.join
|
230
|
+
assert_equal(1, hash_['a1'])
|
231
|
+
assert_equal(2, hash_['b1'])
|
232
|
+
assert_equal(3, hash_['c1'])
|
233
|
+
assert_equal(4, hash_['d1'])
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
extensions: []
|
3
|
+
|
4
|
+
homepage: http://virtuoso.rubyforge.org/blockenspiel
|
5
|
+
executables: []
|
6
|
+
|
7
|
+
version: !ruby/object:Gem::Version
|
8
|
+
version: 0.2.0.1
|
9
|
+
post_install_message:
|
10
|
+
date: 2009-04-16 07:00:00 +00:00
|
11
|
+
files:
|
12
|
+
- ext/blockenspiel/unmixer.c
|
13
|
+
- ext/blockenspiel/extconf.rb
|
14
|
+
- ext/blockenspiel/BlockenspielUnmixerService.java
|
15
|
+
- lib/blockenspiel.rb
|
16
|
+
- lib/blockenspiel/impl.rb
|
17
|
+
- lib/blockenspiel/version.rb
|
18
|
+
- tests/tc_basic.rb
|
19
|
+
- tests/tc_behaviors.rb
|
20
|
+
- tests/tc_dsl_methods.rb
|
21
|
+
- tests/tc_dynamic.rb
|
22
|
+
- tests/tc_mixins.rb
|
23
|
+
- History.rdoc
|
24
|
+
- ImplementingDSLblocks.rdoc
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- lib/blockenspiel_unmixer.jar
|
28
|
+
rubygems_version: 1.3.1
|
29
|
+
rdoc_options: []
|
30
|
+
|
31
|
+
signing_key:
|
32
|
+
cert_chain: []
|
33
|
+
|
34
|
+
name: blockenspiel
|
35
|
+
has_rdoc: true
|
36
|
+
platform: java
|
37
|
+
summary: Blockenspiel is a helper library designed to make it easy to implement DSL
|
38
|
+
blocks.
|
39
|
+
default_executable:
|
40
|
+
bindir: bin
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
version:
|
43
|
+
requirements:
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
version:
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.8.6
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
specification_version: 2
|
56
|
+
test_files:
|
57
|
+
- tests/tc_basic.rb
|
58
|
+
- tests/tc_behaviors.rb
|
59
|
+
- tests/tc_dsl_methods.rb
|
60
|
+
- tests/tc_dynamic.rb
|
61
|
+
- tests/tc_mixins.rb
|
62
|
+
dependencies: []
|
63
|
+
|
64
|
+
description: Blockenspiel is a helper library designed to make it easy to implement
|
65
|
+
DSL blocks. It is designed to be comprehensive and robust, supporting most common
|
66
|
+
usage patterns, and working correctly in the presence of nested blocks and multithreading.
|
67
|
+
email: dazuma@gmail.com
|
68
|
+
authors:
|
69
|
+
- Daniel Azuma
|
70
|
+
extra_rdoc_files:
|
71
|
+
- README.rdoc
|
72
|
+
- History.rdoc
|
73
|
+
- ImplementingDSLblocks.rdoc
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project: virtuoso
|
77
|
+
autorequire:
|