blockenspiel 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Blockenspiel.rdoc +5 -1
- data/History.rdoc +7 -0
- data/README.rdoc +6 -2
- data/Version +1 -1
- data/ext/unmixer_mri/extconf.rb +10 -10
- data/ext/unmixer_mri/unmixer_mri.c +10 -10
- data/lib/blockenspiel.rb +7 -7
- data/lib/blockenspiel/builder.rb +52 -52
- data/lib/blockenspiel/dsl_setup.rb +86 -86
- data/lib/blockenspiel/errors.rb +18 -18
- data/lib/blockenspiel/impl.rb +116 -116
- data/lib/blockenspiel/unmixer_rubinius.rb +22 -22
- data/lib/blockenspiel/unmixer_unimplemented.rb +17 -17
- data/lib/blockenspiel/version.rb +9 -9
- data/lib/blockenspiel/versionomy.rb +11 -13
- data/test/tc_basic.rb +38 -38
- data/test/tc_behaviors.rb +36 -36
- data/test/tc_dsl_attrs.rb +37 -37
- data/test/tc_dsl_methods.rb +86 -86
- data/test/tc_dynamic.rb +39 -39
- data/test/tc_embedded_block.rb +29 -28
- data/test/tc_mixins.rb +103 -68
- data/test/tc_modules.rb +49 -49
- data/test/tc_version.rb +59 -0
- metadata +27 -29
- data/lib/blockenspiel_unmixer_jruby.jar +0 -0
data/Blockenspiel.rdoc
CHANGED
@@ -326,10 +326,14 @@ multiple threads trying to mix methods into the same object concurrently.
|
|
326
326
|
|
327
327
|
=== Development and support
|
328
328
|
|
329
|
-
Documentation is available at http://
|
329
|
+
Documentation is available at http://dazuma.github.com/blockenspiel/rdoc
|
330
330
|
|
331
331
|
Source code is hosted on Github at http://github.com/dazuma/blockenspiel
|
332
332
|
|
333
|
+
Contributions are welcome. Fork the project on Github.
|
334
|
+
|
335
|
+
Build status: {<img src="https://secure.travis-ci.org/dazuma/blockenspiel.png" />}[http://travis-ci.org/dazuma/blockenspiel]
|
336
|
+
|
333
337
|
Report bugs on Github issues at http://github.org/dazuma/blockenspiel/issues
|
334
338
|
|
335
339
|
Contact the author at dazuma at gmail dot com.
|
data/History.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.4.4 / 2012-06-27
|
2
|
+
|
3
|
+
* Under JRuby 1.9 mode, if two threads mixed into the same object, the calls sometimes went to the wrong place. Fixed.
|
4
|
+
* The VERSION constant behaved very oddly under Rubinius 1.9 mode. Fixed.
|
5
|
+
* Eliminate some warnings.
|
6
|
+
* Integrate with Travis CI.
|
7
|
+
|
1
8
|
=== 0.4.3 / 2011-06-22
|
2
9
|
|
3
10
|
* MRI C extension experienced a compile error under the current MRI head (e.g. 1.9.3). Fixed.
|
data/README.rdoc
CHANGED
@@ -74,10 +74,14 @@ For an extended analysis of different ways to implement DSL blocks, see
|
|
74
74
|
|
75
75
|
=== Development and support
|
76
76
|
|
77
|
-
Documentation is available at http://
|
77
|
+
Documentation is available at http://dazuma.github.com/blockenspiel/rdoc
|
78
78
|
|
79
79
|
Source code is hosted on Github at http://github.com/dazuma/blockenspiel
|
80
80
|
|
81
|
+
Contributions are welcome. Fork the project on Github.
|
82
|
+
|
83
|
+
Build status: {<img src="https://secure.travis-ci.org/dazuma/blockenspiel.png" />}[http://travis-ci.org/dazuma/blockenspiel]
|
84
|
+
|
81
85
|
Report bugs on Github issues at http://github.org/dazuma/blockenspiel/issues
|
82
86
|
|
83
87
|
Contact the author at dazuma at gmail dot com.
|
@@ -105,7 +109,7 @@ Luis Lavena.
|
|
105
109
|
|
106
110
|
=== License
|
107
111
|
|
108
|
-
Copyright 2008-
|
112
|
+
Copyright 2008-2012 Daniel Azuma.
|
109
113
|
|
110
114
|
All rights reserved.
|
111
115
|
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.4
|
data/ext/unmixer_mri/extconf.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Blockenspiel native library builder
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2010-2011 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,13 +35,13 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
if ::RUBY_DESCRIPTION =~ /^jruby\s/
|
38
|
-
|
38
|
+
|
39
39
|
::File.open('Makefile', 'w'){ |f_| f_.write(".PHONY: install\ninstall:\n") }
|
40
|
-
|
40
|
+
|
41
41
|
else
|
42
|
-
|
42
|
+
|
43
43
|
require 'mkmf'
|
44
44
|
have_header('ruby/backward/classext.h')
|
45
45
|
create_makefile 'blockenspiel/unmixer_mri'
|
46
|
-
|
46
|
+
|
47
47
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
/*
|
2
2
|
-----------------------------------------------------------------------------
|
3
|
-
|
3
|
+
|
4
4
|
Blockenspiel unmixer (MRI implementation)
|
5
|
-
|
5
|
+
|
6
6
|
-----------------------------------------------------------------------------
|
7
7
|
Copyright 2008-2011 Daniel Azuma
|
8
|
-
|
8
|
+
|
9
9
|
All rights reserved.
|
10
|
-
|
10
|
+
|
11
11
|
Redistribution and use in source and binary forms, with or without
|
12
12
|
modification, are permitted provided that the following conditions are met:
|
13
|
-
|
13
|
+
|
14
14
|
* Redistributions of source code must retain the above copyright notice,
|
15
15
|
this list of conditions and the following disclaimer.
|
16
16
|
* Redistributions in binary form must reproduce the above copyright notice,
|
@@ -19,7 +19,7 @@
|
|
19
19
|
* Neither the name of the copyright holder, nor the names of any other
|
20
20
|
contributors to this software, may be used to endorse or promote products
|
21
21
|
derived from this software without specific prior written permission.
|
22
|
-
|
22
|
+
|
23
23
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
24
24
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
25
25
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -40,9 +40,9 @@
|
|
40
40
|
written by Patrick Farley, anonymous z, Dan Manges, and Clint Bishop.
|
41
41
|
http://rubyforge.org/projects/mixology
|
42
42
|
http://github.com/dan-manges/mixology/tree/master
|
43
|
-
|
43
|
+
|
44
44
|
It has been stripped down and modified for compatibility with Ruby 1.9.
|
45
|
-
|
45
|
+
|
46
46
|
Note that this C extension is specific to MRI.
|
47
47
|
*/
|
48
48
|
|
@@ -95,9 +95,9 @@ static VALUE do_unmix(VALUE self, VALUE receiver, VALUE module) {
|
|
95
95
|
|
96
96
|
void Init_unmixer_mri() {
|
97
97
|
#ifndef RUBINIUS
|
98
|
-
|
98
|
+
|
99
99
|
VALUE container = rb_singleton_class(rb_define_module_under(rb_define_module("Blockenspiel"), "Unmixer"));
|
100
100
|
rb_define_method(container, "unmix", do_unmix, 2);
|
101
|
-
|
101
|
+
|
102
102
|
#endif
|
103
103
|
}
|
data/lib/blockenspiel.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Blockenspiel entry point
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2008-2011 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,7 +35,7 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
# == Blockenspiel
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# The Blockenspiel module provides a namespace for Blockenspiel, as well as
|
40
40
|
# the main entry point method "invoke".
|
41
41
|
|
data/lib/blockenspiel/builder.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Blockenspiel dynamic target construction
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2008-2011 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,37 +35,37 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Blockenspiel
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# === Dynamically construct a target
|
41
|
-
#
|
41
|
+
#
|
42
42
|
# These methods are available in a block passed to Blockenspiel#invoke and
|
43
43
|
# can be used to dynamically define what methods are available from a block.
|
44
44
|
# See Blockenspiel#invoke for more information.
|
45
|
-
|
45
|
+
|
46
46
|
class Builder
|
47
|
-
|
47
|
+
|
48
48
|
include ::Blockenspiel::DSL
|
49
|
-
|
50
|
-
|
49
|
+
|
50
|
+
|
51
51
|
# This is a base class for dynamically constructed targets.
|
52
52
|
# The actual target class is an anonymous subclass of this base class.
|
53
|
-
|
53
|
+
|
54
54
|
class Target # :nodoc:
|
55
|
-
|
55
|
+
|
56
56
|
include ::Blockenspiel::DSL
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
|
59
59
|
# Add a method specification to the subclass.
|
60
|
-
|
60
|
+
|
61
61
|
def self._add_methodinfo(name_, block_, yields_)
|
62
62
|
(@_blockenspiel_methodinfo ||= {})[name_] = [block_, yields_]
|
63
63
|
module_eval("def #{name_}(*params_, &block_); self.class._invoke_methodinfo(:#{name_}, params_, block_); end\n")
|
64
64
|
end
|
65
|
-
|
66
|
-
|
65
|
+
|
66
|
+
|
67
67
|
# Attempt to invoke the given method on the subclass.
|
68
|
-
|
68
|
+
|
69
69
|
def self._invoke_methodinfo(name_, params_, block_)
|
70
70
|
info_ = @_blockenspiel_methodinfo[name_]
|
71
71
|
case info_[1]
|
@@ -76,72 +76,72 @@ module Blockenspiel
|
|
76
76
|
end
|
77
77
|
info_[0].call(*params_, &block_)
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
end
|
81
|
-
|
82
|
-
|
81
|
+
|
82
|
+
|
83
83
|
# Sets up the dynamic target class.
|
84
|
-
|
84
|
+
|
85
85
|
def initialize # :nodoc:
|
86
86
|
@target_class = ::Class.new(::Blockenspiel::Builder::Target)
|
87
87
|
@target_class.dsl_methods(false)
|
88
88
|
end
|
89
|
-
|
90
|
-
|
89
|
+
|
90
|
+
|
91
91
|
# Creates a new instance of the dynamic target class
|
92
|
-
|
92
|
+
|
93
93
|
def _create_target # :nodoc:
|
94
94
|
@target_class.new
|
95
95
|
end
|
96
|
-
|
97
|
-
|
96
|
+
|
97
|
+
|
98
98
|
# === Declare a DSL method.
|
99
|
-
#
|
99
|
+
#
|
100
100
|
# This call creates a method that can be called from the DSL block.
|
101
101
|
# Provide a name for the method, a block defining the method's
|
102
102
|
# implementation, and an optional hash of options.
|
103
|
-
#
|
103
|
+
#
|
104
104
|
# By default, a method of the same name is also made available to
|
105
105
|
# parameterless blocks. To change the name of the parameterless method,
|
106
106
|
# provide its name as the value of the <tt>:dsl_method</tt> option.
|
107
107
|
# To disable this method for parameterless blocks, set the
|
108
108
|
# <tt>:dsl_method</tt> option to +false+.
|
109
|
-
#
|
109
|
+
#
|
110
110
|
# The <tt>:mixin</tt> option is a deprecated alias for
|
111
111
|
# <tt>:dsl_method</tt>.
|
112
|
-
#
|
112
|
+
#
|
113
113
|
# === Warning about the +return+ keyword
|
114
|
-
#
|
114
|
+
#
|
115
115
|
# Because you are implementing your method using a block, remember the
|
116
116
|
# distinction between <tt>Proc.new</tt> and +lambda+. Invoking +return+
|
117
117
|
# from the former does not return from the block, but returns from the
|
118
118
|
# surrounding method scope. Since normal blocks passed to methods are
|
119
119
|
# of the former type, be very careful about using the +return+ keyword:
|
120
|
-
#
|
120
|
+
#
|
121
121
|
# add_method(:foo) do |param|
|
122
122
|
# puts "foo called with parameter "+param.inspect
|
123
123
|
# return "a return value" # DOESN'T WORK LIKE YOU EXPECT!
|
124
124
|
# end
|
125
|
-
#
|
125
|
+
#
|
126
126
|
# To return a value from the method you are creating, set the evaluation
|
127
127
|
# value at the end of the block:
|
128
|
-
#
|
128
|
+
#
|
129
129
|
# add_method(:foo) do |param|
|
130
130
|
# puts "foo called with parameter "+param.inspect
|
131
131
|
# "a return value" # Returns from method foo
|
132
132
|
# end
|
133
|
-
#
|
133
|
+
#
|
134
134
|
# If you must use the +return+ keyword, create your block as a lambda
|
135
135
|
# as in this example:
|
136
|
-
#
|
136
|
+
#
|
137
137
|
# code = lambda do |param|
|
138
138
|
# puts "foo called with parameter "+param.inspect
|
139
139
|
# return "a return value" # Returns from method foo
|
140
140
|
# end
|
141
141
|
# add_method(:foo, &code)
|
142
|
-
#
|
142
|
+
#
|
143
143
|
# === Accepting a block argument
|
144
|
-
#
|
144
|
+
#
|
145
145
|
# If you want your method to take a block, you have several options
|
146
146
|
# depending on your Ruby version. If you are running the standard Matz
|
147
147
|
# Ruby interpreter (MRI) version 1.8.7 or later (including 1.9.x), or a
|
@@ -151,16 +151,16 @@ module Blockenspiel
|
|
151
151
|
# Ruby doesn't support invoking such a block with +yield+.
|
152
152
|
# For example, to create a method named "foo" that takes one parameter
|
153
153
|
# and a block, do this:
|
154
|
-
#
|
154
|
+
#
|
155
155
|
# add_method(:foo) do |param, &block|
|
156
156
|
# puts "foo called with parameter "+param.inspect
|
157
157
|
# puts "the block returned "+block.call.inspect
|
158
158
|
# end
|
159
|
-
#
|
159
|
+
#
|
160
160
|
# In your DSL, you can then call:
|
161
|
-
#
|
161
|
+
#
|
162
162
|
# foo("hello"){ "a value" }
|
163
|
-
#
|
163
|
+
#
|
164
164
|
# If you are using MRI 1.8.6, or another Ruby interpreter that doesn't
|
165
165
|
# fully support this syntax (such as JRuby versions older than 1.5),
|
166
166
|
# Blockenspiel provides an alternative in the form of the <tt>:block</tt>
|
@@ -170,7 +170,7 @@ module Blockenspiel
|
|
170
170
|
# prepend or append, respectively, the block (as a +Proc+ object) to
|
171
171
|
# the parameter list. If the caller does not include a block when
|
172
172
|
# calling your DSL method, nil is prepended/appended. For example:
|
173
|
-
#
|
173
|
+
#
|
174
174
|
# add_method(:foo, :block => :last) do |param, block|
|
175
175
|
# puts "foo called with parameter "+param.inspect
|
176
176
|
# if block
|
@@ -179,11 +179,11 @@ module Blockenspiel
|
|
179
179
|
# puts "no block passed"
|
180
180
|
# end
|
181
181
|
# end
|
182
|
-
#
|
182
|
+
#
|
183
183
|
# The <tt>:receive_block</tt> option is a deprecated alternative.
|
184
184
|
# Setting <tt>:receive_block => true</tt> is currently equivalent to
|
185
185
|
# setting <tt>:block => :last</tt>.
|
186
|
-
|
186
|
+
|
187
187
|
def add_method(name_, opts_={}, &block_)
|
188
188
|
receive_block_ = opts_[:receive_block] ? :last : opts_[:block]
|
189
189
|
receive_block_ = :first if receive_block_ && receive_block_ != :last
|
@@ -194,8 +194,8 @@ module Blockenspiel
|
|
194
194
|
@target_class.dsl_method(dsl_method_name_, name_)
|
195
195
|
end
|
196
196
|
end
|
197
|
-
|
197
|
+
|
198
198
|
end
|
199
|
-
|
200
|
-
|
199
|
+
|
200
|
+
|
201
201
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Blockenspiel DSL definition
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2008-2011 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -38,30 +38,30 @@ require 'thread'
|
|
38
38
|
|
39
39
|
|
40
40
|
module Blockenspiel
|
41
|
-
|
42
|
-
|
41
|
+
|
42
|
+
|
43
43
|
# === DSL setup methods
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# These class methods are available after you have included the
|
46
46
|
# Blockenspiel::DSL module.
|
47
|
-
#
|
47
|
+
#
|
48
48
|
# By default, a class that has DSL capability will automatically make
|
49
49
|
# all public methods available to parameterless blocks, except for the
|
50
50
|
# +initialize+ method, any methods whose names begin with an underscore,
|
51
51
|
# and any methods whose names end with an equals sign.
|
52
|
-
#
|
52
|
+
#
|
53
53
|
# If you want to change this behavior, use the directives defined here to
|
54
54
|
# control exactly which methods are available to parameterless blocks.
|
55
|
-
|
55
|
+
|
56
56
|
module DSLSetupMethods
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
|
59
59
|
# :stopdoc:
|
60
|
-
|
60
|
+
|
61
61
|
# Called when DSLSetupMethods extends a class.
|
62
62
|
# This sets up the current class, and adds a hook that causes
|
63
63
|
# any subclass of the current class also to be set up.
|
64
|
-
|
64
|
+
|
65
65
|
def self.extended(klass_)
|
66
66
|
unless klass_.instance_variable_defined?(:@_blockenspiel_module)
|
67
67
|
_setup_class(klass_)
|
@@ -77,14 +77,14 @@ module Blockenspiel
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
# :startdoc:
|
82
|
-
|
83
|
-
|
82
|
+
|
83
|
+
|
84
84
|
# Set up a class.
|
85
85
|
# Creates a DSL module for this class, optionally delegating to the superclass's module.
|
86
86
|
# Also initializes the class's methods hash and active flag.
|
87
|
-
|
87
|
+
|
88
88
|
def self._setup_class(klass_) # :nodoc:
|
89
89
|
superclass_ = klass_.superclass
|
90
90
|
superclass_ = nil unless superclass_.respond_to?(:_get_blockenspiel_module)
|
@@ -99,10 +99,10 @@ module Blockenspiel
|
|
99
99
|
klass_.instance_variable_set(:@_blockenspiel_methods, {})
|
100
100
|
klass_.instance_variable_set(:@_blockenspiel_active, nil)
|
101
101
|
end
|
102
|
-
|
103
|
-
|
102
|
+
|
103
|
+
|
104
104
|
# Automatically make the given method a DSL method according to the current setting.
|
105
|
-
|
105
|
+
|
106
106
|
def _blockenspiel_auto_dsl_method(symbol_) # :nodoc:
|
107
107
|
if @_blockenspiel_active
|
108
108
|
dsl_method(symbol_)
|
@@ -112,23 +112,23 @@ module Blockenspiel
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
115
|
-
|
116
|
-
|
115
|
+
|
116
|
+
|
117
117
|
# Hook called when a method is added.
|
118
118
|
# This calls _blockenspiel_auto_dsl_method to auto-handle the method,
|
119
119
|
# possibly making it a DSL method according to the current setting.
|
120
|
-
|
120
|
+
|
121
121
|
def method_added(symbol_) # :nodoc:
|
122
122
|
_blockenspiel_auto_dsl_method(symbol_)
|
123
123
|
super
|
124
124
|
end
|
125
|
-
|
126
|
-
|
125
|
+
|
126
|
+
|
127
127
|
# Custom include method. Calls the main include implementation, but also
|
128
128
|
# goes through the public methods of the included module and calls
|
129
129
|
# _blockenspiel_auto_dsl_method on each to make them DSL methods
|
130
130
|
# (possibly) according to the current setting.
|
131
|
-
|
131
|
+
|
132
132
|
def _blockenspiel_custom_include(*modules_) # :nodoc:
|
133
133
|
_blockenspiel_default_include(*modules_)
|
134
134
|
modules_.reverse_each do |mod_|
|
@@ -137,19 +137,19 @@ module Blockenspiel
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
140
|
-
|
141
|
-
|
140
|
+
|
141
|
+
|
142
142
|
# Get this class's corresponding DSL module
|
143
|
-
|
143
|
+
|
144
144
|
def _get_blockenspiel_module # :nodoc:
|
145
145
|
@_blockenspiel_module
|
146
146
|
end
|
147
|
-
|
148
|
-
|
147
|
+
|
148
|
+
|
149
149
|
# Get information on the given DSL method name.
|
150
150
|
# Possible values are the name of the delegate method, false for method disabled,
|
151
151
|
# or nil for method never defined.
|
152
|
-
|
152
|
+
|
153
153
|
def _get_blockenspiel_delegate(name_) # :nodoc:
|
154
154
|
delegate_ = @_blockenspiel_methods[name_]
|
155
155
|
if delegate_.nil? && @_blockenspiel_superclass
|
@@ -158,20 +158,20 @@ module Blockenspiel
|
|
158
158
|
delegate_
|
159
159
|
end
|
160
160
|
end
|
161
|
-
|
162
|
-
|
161
|
+
|
162
|
+
|
163
163
|
# Make a particular method available to parameterless DSL blocks.
|
164
|
-
#
|
164
|
+
#
|
165
165
|
# To explicitly make a method available to parameterless blocks:
|
166
166
|
# dsl_method :my_method
|
167
|
-
#
|
167
|
+
#
|
168
168
|
# To explicitly exclude a method from parameterless blocks:
|
169
169
|
# dsl_method :my_method, false
|
170
|
-
#
|
170
|
+
#
|
171
171
|
# To explicitly make a method available to parameterless blocks, but
|
172
172
|
# point it to a method of a different name on the target class:
|
173
173
|
# dsl_method :my_method, :target_class_method
|
174
|
-
|
174
|
+
|
175
175
|
def dsl_method(name_, delegate_=nil)
|
176
176
|
name_ = name_.to_sym
|
177
177
|
if delegate_
|
@@ -184,35 +184,35 @@ module Blockenspiel
|
|
184
184
|
@_blockenspiel_module.module_eval("def #{name_}(*params_, &block_); val_ = ::Blockenspiel._target_dispatch(self, :#{name_}, params_, block_); ::Blockenspiel::NO_VALUE.equal?(val_) ? super(*params_, &block_) : val_; end\n")
|
185
185
|
end
|
186
186
|
end
|
187
|
-
|
188
|
-
|
187
|
+
|
188
|
+
|
189
189
|
# Control the behavior of methods with respect to parameterless blocks,
|
190
190
|
# or make a list of methods available to parameterless blocks in bulk.
|
191
|
-
#
|
191
|
+
#
|
192
192
|
# To enable automatic exporting of methods to parameterless blocks.
|
193
193
|
# After executing this command, all public methods defined in the class
|
194
194
|
# will be available on parameterless blocks, until
|
195
195
|
# <tt>dsl_methods false</tt> is called:
|
196
196
|
# dsl_methods true
|
197
|
-
#
|
197
|
+
#
|
198
198
|
# To disable automatic exporting of methods to parameterless blocks.
|
199
199
|
# After executing this command, methods defined in this class will be
|
200
200
|
# excluded from parameterless blocks, until <tt>dsl_methods true</tt>
|
201
201
|
# is called:
|
202
202
|
# dsl_methods false
|
203
|
-
#
|
203
|
+
#
|
204
204
|
# To make a list of methods available to parameterless blocks in bulk:
|
205
205
|
# dsl_methods :my_method1, :my_method2, ...
|
206
|
-
#
|
206
|
+
#
|
207
207
|
# You can also point dsl methods to a method of a different name on the
|
208
208
|
# target class, by using a hash syntax, as follows:
|
209
209
|
# dsl_methods :my_method1 => :target_class_method1,
|
210
210
|
# :my_method2 => :target_class_method2
|
211
|
-
#
|
211
|
+
#
|
212
212
|
# You can mix non-renamed and renamed method declarations as long as
|
213
213
|
# the renamed (hash) methods are at the end. e.g.:
|
214
214
|
# dsl_methods :my_method1, :my_method2 => :target_class_method2
|
215
|
-
|
215
|
+
|
216
216
|
def dsl_methods(*names_)
|
217
217
|
if names_.size == 0 || names_ == [true]
|
218
218
|
@_blockenspiel_active = true
|
@@ -229,10 +229,10 @@ module Blockenspiel
|
|
229
229
|
end
|
230
230
|
end
|
231
231
|
end
|
232
|
-
|
233
|
-
|
232
|
+
|
233
|
+
|
234
234
|
# A DSL-friendly attr_accessor.
|
235
|
-
#
|
235
|
+
#
|
236
236
|
# This creates the usual "name" and "name=" methods in the current
|
237
237
|
# class that can be used in the usual way. However, its implementation
|
238
238
|
# of the "name" method (the getter) also takes an optional parameter
|
@@ -240,26 +240,26 @@ module Blockenspiel
|
|
240
240
|
# setter syntax cannot be used in a parameterless block, since it is
|
241
241
|
# syntactically indistinguishable from a local variable assignment.
|
242
242
|
# The "name" method is exposed as a dsl_method.
|
243
|
-
#
|
243
|
+
#
|
244
244
|
# For example:
|
245
|
-
#
|
245
|
+
#
|
246
246
|
# dsl_attr_accessor :foo
|
247
|
-
#
|
247
|
+
#
|
248
248
|
# enables the following:
|
249
|
-
#
|
249
|
+
#
|
250
250
|
# my_block do |param|
|
251
251
|
# param.foo = 1 # Usual setter syntax works
|
252
252
|
# param.foo 2 # Alternate setter syntax also works
|
253
253
|
# puts param.foo # Usual getter syntax still works
|
254
254
|
# end
|
255
|
-
#
|
255
|
+
#
|
256
256
|
# my_block do
|
257
257
|
# # foo = 1 # Usual setter syntax does NOT work since it
|
258
258
|
# # looks like a local variable assignment
|
259
259
|
# foo 2 # Alternate setter syntax does work
|
260
260
|
# puts foo # Usual getter syntax still works
|
261
261
|
# end
|
262
|
-
|
262
|
+
|
263
263
|
def dsl_attr_accessor(*names_)
|
264
264
|
names_.each do |name_|
|
265
265
|
unless name_.kind_of?(::String) || name_.kind_of?(::Symbol)
|
@@ -273,29 +273,29 @@ module Blockenspiel
|
|
273
273
|
dsl_method(name_)
|
274
274
|
end
|
275
275
|
end
|
276
|
-
|
277
|
-
|
276
|
+
|
277
|
+
|
278
278
|
# A DSL-friendly attr_writer.
|
279
|
-
#
|
279
|
+
#
|
280
280
|
# This creates the usual "name=" method in the current class that can
|
281
281
|
# be used in the usual way. However, it also creates the method "name",
|
282
282
|
# which also functions as a setter (but not a getter). This is done
|
283
283
|
# because the usual setter syntax cannot be used in a parameterless
|
284
284
|
# block, since it is syntactically indistinguishable from a local
|
285
285
|
# variable assignment. The "name" method is exposed as a dsl_method.
|
286
|
-
#
|
286
|
+
#
|
287
287
|
# For example:
|
288
|
-
#
|
288
|
+
#
|
289
289
|
# dsl_attr_writer :foo
|
290
|
-
#
|
290
|
+
#
|
291
291
|
# is functionally equivalent to:
|
292
|
-
#
|
292
|
+
#
|
293
293
|
# attr_writer :foo
|
294
294
|
# alias_method :foo, :foo=
|
295
295
|
# dsl_method :foo
|
296
|
-
#
|
296
|
+
#
|
297
297
|
# which enables the following:
|
298
|
-
#
|
298
|
+
#
|
299
299
|
# my_block do |param|
|
300
300
|
# param.foo = 1 # Usual setter syntax works
|
301
301
|
# param.foo 2 # Alternate setter syntax also works
|
@@ -305,7 +305,7 @@ module Blockenspiel
|
|
305
305
|
# # looks like a local variable assignment
|
306
306
|
# foo(2) # Alternate setter syntax does work
|
307
307
|
# end
|
308
|
-
|
308
|
+
|
309
309
|
def dsl_attr_writer(*names_)
|
310
310
|
names_.each do |name_|
|
311
311
|
attr_writer(name_)
|
@@ -313,49 +313,49 @@ module Blockenspiel
|
|
313
313
|
dsl_method(name_)
|
314
314
|
end
|
315
315
|
end
|
316
|
-
|
317
|
-
|
316
|
+
|
317
|
+
|
318
318
|
end
|
319
|
-
|
320
|
-
|
319
|
+
|
320
|
+
|
321
321
|
# === DSL activation module
|
322
|
-
#
|
322
|
+
#
|
323
323
|
# Include this module in a class to mark this class as a DSL class and
|
324
324
|
# make it possible for its methods to be called from a block that does not
|
325
325
|
# take a parameter.
|
326
|
-
#
|
326
|
+
#
|
327
327
|
# After you include this module, you can use the directives defined in
|
328
328
|
# DSLSetupMethods to control what methods are available to DSL blocks
|
329
329
|
# that do not take parameters.
|
330
|
-
|
330
|
+
|
331
331
|
module DSL
|
332
|
-
|
332
|
+
|
333
333
|
def self.included(klass_) # :nodoc:
|
334
334
|
unless klass_.kind_of?(::Class)
|
335
335
|
raise ::Blockenspiel::BlockenspielError, "You cannot include Blockenspiel::DSL in a module (yet)"
|
336
336
|
end
|
337
337
|
klass_.extend(::Blockenspiel::DSLSetupMethods)
|
338
338
|
end
|
339
|
-
|
339
|
+
|
340
340
|
end
|
341
|
-
|
342
|
-
|
341
|
+
|
342
|
+
|
343
343
|
# === DSL activation base class
|
344
|
-
#
|
344
|
+
#
|
345
345
|
# Subclasses of this base class are considered DSL classes.
|
346
346
|
# Methods of the class can be made available to be called from a block that
|
347
347
|
# doesn't take an explicit block parameter.
|
348
348
|
# You may use the directives defined in DSLSetupMethods to control how
|
349
349
|
# methods of the class are handled in such blocks.
|
350
|
-
#
|
350
|
+
#
|
351
351
|
# Subclassing this base class is functionally equivalent to simply
|
352
352
|
# including Blockenspiel::DSL in the class.
|
353
|
-
|
353
|
+
|
354
354
|
class Base
|
355
|
-
|
355
|
+
|
356
356
|
include ::Blockenspiel::DSL
|
357
|
-
|
357
|
+
|
358
358
|
end
|
359
|
-
|
360
|
-
|
359
|
+
|
360
|
+
|
361
361
|
end
|