blockenspiel 0.4.5 → 0.5.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.
- checksums.yaml +7 -0
- data/Blockenspiel.rdoc +48 -42
- data/History.rdoc +14 -0
- data/README.rdoc +20 -19
- data/Version +1 -1
- data/lib/blockenspiel.rb +2 -2
- data/lib/blockenspiel/builder.rb +1 -1
- data/lib/blockenspiel/dsl_setup.rb +1 -1
- data/lib/blockenspiel/errors.rb +1 -1
- data/lib/blockenspiel/impl.rb +60 -48
- data/lib/blockenspiel/unmixer_rubinius.rb +18 -3
- data/lib/blockenspiel/unmixer_unimplemented.rb +4 -1
- data/lib/blockenspiel/version.rb +1 -1
- data/lib/blockenspiel/versionomy.rb +1 -1
- data/lib/blockenspiel_unmixer_jruby.jar +0 -0
- data/test/tc_basic.rb +9 -8
- data/test/tc_behaviors.rb +9 -9
- data/test/tc_dsl_attrs.rb +2 -2
- data/test/tc_dsl_methods.rb +10 -10
- data/test/tc_dynamic.rb +5 -5
- data/test/tc_embedded_block.rb +2 -2
- data/test/tc_mixins.rb +40 -22
- data/test/tc_modules.rb +3 -3
- data/test/tc_version.rb +3 -3
- metadata +17 -21
- data/ext/unmixer_mri/extconf.rb +0 -47
- data/ext/unmixer_mri/unmixer_mri.c +0 -103
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bad96a420e759925ce030818a785e845b0b7a426
|
4
|
+
data.tar.gz: 2671c4e900ce470cc51f244d4bc0faaf0c394cbe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3df2c3683828d0b4ab0749fe39b71dddb92945c43df25ab0f64bba65c51c78eb7f90b27a42ceb4d8dcf4bd64dde973522fdcd36d5f8061aad220ccfdd31c058a
|
7
|
+
data.tar.gz: 186032fa3c700bff84fc7ced3a2d1c4c472670ddfdcb09623a324611d3751567711253bc4bad28ac720f7049650ed9ea74b66dcded1884be0b2b0f023f7eda0a
|
data/Blockenspiel.rdoc
CHANGED
@@ -90,7 +90,7 @@ You could write this as follows:
|
|
90
90
|
# do something
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
def configure_me
|
95
95
|
yield ConfigMethods.new
|
96
96
|
end
|
@@ -130,8 +130,8 @@ doesn't take a parameter, the second form without a parameter is used.
|
|
130
130
|
=== How does that help me? (Or, why not just use instance_eval?)
|
131
131
|
|
132
132
|
As noted earlier, some libraries that provide parameter-less DSL blocks use
|
133
|
-
<tt>instance_eval</tt>, and they could even support both the parameter
|
134
|
-
parameter-less mechanisms by checking the block arity:
|
133
|
+
a simple <tt>instance_eval</tt>, and they could even support both the parameter
|
134
|
+
and parameter-less mechanisms by checking the block arity:
|
135
135
|
|
136
136
|
def configure_me(&block)
|
137
137
|
if block.arity == 1
|
@@ -151,7 +151,7 @@ methods inside the block:
|
|
151
151
|
def callers_helper_method
|
152
152
|
# ...
|
153
153
|
end
|
154
|
-
|
154
|
+
|
155
155
|
configure_me do
|
156
156
|
add_foo(1)
|
157
157
|
callers_helper_method # Error! self is now an instance of ConfigMethods
|
@@ -159,21 +159,13 @@ methods inside the block:
|
|
159
159
|
add_bar(2)
|
160
160
|
end
|
161
161
|
|
162
|
-
Blockenspiel
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
<tt>add_foo</tt> and <tt>add_bar</tt> methods are also made available
|
170
|
-
temporarily for the duration of the block. When called, they are intercepted
|
171
|
-
and redirected to your +ConfigMethods+ instance just as if you had called
|
172
|
-
them directly via a block parameter. Blockenspiel handles the object
|
173
|
-
redirection behind the scenes so you do not have to think about it. With
|
174
|
-
Blockenspiel, the caller retains access to its helper methods, and even its
|
175
|
-
own instance variables, within the block, because +self+ has not been
|
176
|
-
modified.
|
162
|
+
Blockenspiel employs a number of techniques to mitigate the ill effects of
|
163
|
+
<tt>instance_eval</tt>. It delegates methods that are not part of the DSL,
|
164
|
+
back to the enclosing context object, so that the caller retains access to
|
165
|
+
helper methods. It also includes an optional experimental technique (not
|
166
|
+
available on all ruby platforms) that temporarily mixes the DSL methods
|
167
|
+
directly into the caller's +self+ object, so that instance variable access
|
168
|
+
is retained.
|
177
169
|
|
178
170
|
=== Is that it?
|
179
171
|
|
@@ -196,28 +188,28 @@ a few examples:
|
|
196
188
|
|
197
189
|
class ConfigMethods
|
198
190
|
include Blockenspiel::DSL
|
199
|
-
|
191
|
+
|
200
192
|
def add_foo # automatically added to the dsl
|
201
193
|
# do stuff...
|
202
194
|
end
|
203
|
-
|
195
|
+
|
204
196
|
def my_private_method
|
205
197
|
# do stuff...
|
206
198
|
end
|
207
199
|
dsl_method :my_private_method, false # remove from the dsl
|
208
|
-
|
200
|
+
|
209
201
|
dsl_methods false # stop automatically adding methods to the dsl
|
210
|
-
|
202
|
+
|
211
203
|
def another_private_method # not added
|
212
204
|
# do stuff...
|
213
205
|
end
|
214
|
-
|
206
|
+
|
215
207
|
dsl_methods true # resume automatically adding methods to the dsl
|
216
|
-
|
208
|
+
|
217
209
|
def add_bar # this method is automatically added
|
218
210
|
# do stuff...
|
219
211
|
end
|
220
|
-
|
212
|
+
|
221
213
|
def add_baz
|
222
214
|
# do stuff
|
223
215
|
end
|
@@ -233,12 +225,12 @@ Parameterless blocks do not support <tt>attr_writer</tt> (or, by corollary,
|
|
233
225
|
configure_me do |config|
|
234
226
|
config.foo = 1 # works fine when the block has a parameter
|
235
227
|
end
|
236
|
-
|
228
|
+
|
237
229
|
configure_me do
|
238
230
|
# foo = 1 # <--- Doesn't work: looks like a variable assignment
|
239
231
|
set_foo(1) # <--- Fix it by renaming to this instead
|
240
232
|
end
|
241
|
-
|
233
|
+
|
242
234
|
# This is implemented like this::
|
243
235
|
class ConfigMethods
|
244
236
|
include Blockenspiel::DSL
|
@@ -256,7 +248,7 @@ parameterless block:
|
|
256
248
|
foo 1 # this syntax is now supported.
|
257
249
|
puts "foo is #{foo}" # The getter still works.
|
258
250
|
end
|
259
|
-
|
251
|
+
|
260
252
|
# This is implemented like this::
|
261
253
|
class ConfigMethods
|
262
254
|
include Blockenspiel::DSL
|
@@ -302,12 +294,26 @@ Blockenspiel also correctly handles nested blocks. e.g.
|
|
302
294
|
end
|
303
295
|
end
|
304
296
|
|
305
|
-
|
306
|
-
|
297
|
+
Blockenspiel provides three strategies for doing parameterless DSL blocks.
|
298
|
+
|
299
|
+
The default strategy uses a proxy object that delegates unrecognized methods
|
300
|
+
out to the calling context. It should work well for most cases.
|
301
|
+
|
302
|
+
Second, some applications might want to use the simple <tt>instance_eval</tt>
|
303
|
+
behavior. RSpec is a good example of such a case, since the DSL is being used
|
304
|
+
to construct objects, so it makes sense for instance variables inside the block
|
305
|
+
to belong to the object being constructed.
|
306
|
+
|
307
|
+
Third, an experimental mixin strategy is provided, which adds the DSL methods
|
308
|
+
directly to the context's self object, and removes them afterward. This is
|
309
|
+
available on Rubinius and JRuby but not on MRI.
|
310
|
+
|
311
|
+
Finally, Blockenspiel is thread safe, correctly handling, for example, the case
|
312
|
+
of multiple threads trying to mix methods into the same object concurrently.
|
307
313
|
|
308
314
|
=== Requirements
|
309
315
|
|
310
|
-
* Ruby 1.
|
316
|
+
* Ruby 1.9.3 or later, JRuby 1.5 or later, or Rubinius 1.0 or later.
|
311
317
|
|
312
318
|
=== Installation
|
313
319
|
|
@@ -320,9 +326,7 @@ multiple threads trying to mix methods into the same object concurrently.
|
|
320
326
|
whether it is even a reasonable feature at all.
|
321
327
|
* Including Blockenspiel::DSL in a module (rather than a class) is not yet
|
322
328
|
supported, but this is planned for a future release.
|
323
|
-
*
|
324
|
-
native extension. I'm considering evaluating Luis Lavena's rake-compiler
|
325
|
-
to simplify this process.
|
329
|
+
* Find a way to implement mixin behavior reliably on MRI.
|
326
330
|
|
327
331
|
=== Development and support
|
328
332
|
|
@@ -349,19 +353,21 @@ copies or mirrors out there.
|
|
349
353
|
|
350
354
|
The unmixer code is based on {Mixology}[http://rubyforge.org/projects/mixology],
|
351
355
|
version by Patrick Farley, anonymous z, Dan Manges, and Clint Bishop.
|
352
|
-
The
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
356
|
+
The JRuby code is adapted from Mixology 0.1, and has been stripped down and
|
357
|
+
modified to support JRuby >= 1.2. The Rubinius code was adapted from unreleased
|
358
|
+
code in the Mixology source tree and modified to support Rubinius 1.0. I know
|
359
|
+
Mixology 0.2 is now available, but its Rubinius support is not active, and I'd
|
360
|
+
rather keep the unmixer bundled with Blockenspiel for now to reduce
|
361
|
+
dependencies. Earlier versions of Blockenspiel also included a C extension,
|
362
|
+
adapted from Mixology, to support mixins for MRI, but this code has been
|
363
|
+
disabled due to issues with newer versions of Ruby.
|
358
364
|
|
359
365
|
The dsl_attr_writer and dsl_attr_accessor feature came from a suggestion by
|
360
366
|
Luis Lavena.
|
361
367
|
|
362
368
|
=== License
|
363
369
|
|
364
|
-
Copyright 2008
|
370
|
+
Copyright 2008 Daniel Azuma.
|
365
371
|
|
366
372
|
All rights reserved.
|
367
373
|
|
data/History.rdoc
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 0.5.0 / 2016-01-07
|
2
|
+
|
3
|
+
* Fixed an issue with the proxy strategy, where if a block spawns blocks that live longer than it, the sub-blocks lost their context.
|
4
|
+
* Changed the default strategy to proxy due to semantic issues with mixin and difficulty supporting it.
|
5
|
+
* Dropped support for the mixin strategy on MRI because Ruby 2.3.0 broke it and I don't have the bandwidth to find a remedy.
|
6
|
+
* Updated the Rakefile, tests, and general infrastructure to play better with modern Rubies.
|
7
|
+
* Dropped support for Ruby 1.8, because who still uses 1.8???
|
8
|
+
|
9
|
+
=== 0.4.6 / (never actually released)
|
10
|
+
|
11
|
+
* Compatibility with the signature change to reset_method_cache in recent builds of Rubinius 2.0.
|
12
|
+
* The gemspec no longer includes the timestamp in the version, so that bundler can pull from github. (Reported by corneverbruggen)
|
13
|
+
* The Rakefile is now compatible with Ruby 2.0 and RubyGems 2.0.
|
14
|
+
|
1
15
|
=== 0.4.5 / 2012-06-27
|
2
16
|
|
3
17
|
* The 0.4.4 build was missing the JRuby unmixer. Fixed.
|
data/README.rdoc
CHANGED
@@ -16,7 +16,7 @@ and those that do not. For example:
|
|
16
16
|
config.add_foo(1)
|
17
17
|
config.add_bar(2)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# Call DSL block without parameter
|
21
21
|
configure_me do
|
22
22
|
add_foo(3)
|
@@ -35,17 +35,18 @@ To support the above usage, you can do this:
|
|
35
35
|
# do something
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Implement configure_me method
|
40
40
|
def configure_me(&block)
|
41
41
|
Blockenspiel.invoke(block, ConfigMethods.new)
|
42
42
|
end
|
43
43
|
|
44
|
-
By default, Blockenspiel uses a
|
45
|
-
|
46
|
-
|
44
|
+
By default, Blockenspiel uses a "delegation" technique (to my knowledge first
|
45
|
+
proposed by Dan Manges) to support parameterless blocks while mitigating some
|
46
|
+
of the issues with <tt>instance_eval</tt>. It supports nested blocks and
|
47
47
|
multithreaded access, and provides a variety of tools for handling the
|
48
|
-
typical issues you may encounter when writing DSLs.
|
48
|
+
typical issues you may encounter when writing DSLs. On some ruby platforms,
|
49
|
+
Blockenspiel also supports a mixin technique (proposed by Why The Lucky Stiff).
|
49
50
|
|
50
51
|
For more detailed usage and examples, see
|
51
52
|
{Blockenspiel.rdoc}[link:Blockenspiel\_rdoc.html].
|
@@ -55,7 +56,7 @@ For an extended analysis of different ways to implement DSL blocks, see
|
|
55
56
|
|
56
57
|
=== Requirements
|
57
58
|
|
58
|
-
* Ruby 1.
|
59
|
+
* Ruby 1.9.3 or later, JRuby 1.5 or later, or Rubinius 1.0 or later.
|
59
60
|
|
60
61
|
=== Installation
|
61
62
|
|
@@ -66,11 +67,9 @@ For an extended analysis of different ways to implement DSL blocks, see
|
|
66
67
|
* Implementing wildcard DSL methods using <tt>method_missing</tt> doesn't
|
67
68
|
work. I haven't yet decided on the right semantics for this case, or
|
68
69
|
whether it is even a reasonable feature at all.
|
69
|
-
* Including Blockenspiel::DSL in a module (rather than a class) is not
|
70
|
-
supported, but this
|
71
|
-
*
|
72
|
-
native extension. I'm considering evaluating Luis Lavena's rake-compiler
|
73
|
-
to simplify this process.
|
70
|
+
* Including Blockenspiel::DSL in a module (rather than a class) is not
|
71
|
+
supported, but this could appear in a future release.
|
72
|
+
* Find a way to implement mixin behavior reliably on MRI.
|
74
73
|
|
75
74
|
=== Development and support
|
76
75
|
|
@@ -97,19 +96,21 @@ its author, but you may find copies or mirrors out there.
|
|
97
96
|
|
98
97
|
The unmixer code is based on {Mixology}[http://rubyforge.org/projects/mixology],
|
99
98
|
version by Patrick Farley, anonymous z, Dan Manges, and Clint Bishop.
|
100
|
-
The
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
99
|
+
The JRuby code is adapted from Mixology 0.1, and has been stripped down and
|
100
|
+
modified to support JRuby >= 1.2. The Rubinius code was adapted from unreleased
|
101
|
+
code in the Mixology source tree and modified to support Rubinius 1.0. I know
|
102
|
+
Mixology 0.2 is now available, but its Rubinius support is not active, and I'd
|
103
|
+
rather keep the unmixer bundled with Blockenspiel for now to reduce
|
104
|
+
dependencies. Earlier versions of Blockenspiel also included a C extension,
|
105
|
+
adapted from Mixology, to support mixins for MRI, but this code has been
|
106
|
+
disabled due to issues with newer versions of Ruby.
|
106
107
|
|
107
108
|
The dsl_attr_writer and dsl_attr_accessor feature came from a suggestion by
|
108
109
|
Luis Lavena.
|
109
110
|
|
110
111
|
=== License
|
111
112
|
|
112
|
-
Copyright 2008
|
113
|
+
Copyright 2008 Daniel Azuma.
|
113
114
|
|
114
115
|
All rights reserved.
|
115
116
|
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/blockenspiel.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Blockenspiel entry point
|
4
4
|
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
|
-
# Copyright 2008
|
6
|
+
# Copyright 2008 Daniel Azuma
|
7
7
|
#
|
8
8
|
# All rights reserved.
|
9
9
|
#
|
@@ -45,7 +45,7 @@ end
|
|
45
45
|
|
46
46
|
case ::RUBY_DESCRIPTION
|
47
47
|
when /^ruby\s/
|
48
|
-
require 'blockenspiel/
|
48
|
+
require 'blockenspiel/unmixer_unimplemented'
|
49
49
|
when /^jruby\s/
|
50
50
|
require 'blockenspiel_unmixer_jruby'
|
51
51
|
when /^rubinius\s/
|
data/lib/blockenspiel/builder.rb
CHANGED
data/lib/blockenspiel/errors.rb
CHANGED
data/lib/blockenspiel/impl.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Blockenspiel implementation
|
4
4
|
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
|
-
# Copyright 2008
|
6
|
+
# Copyright 2008 Daniel Azuma
|
7
7
|
#
|
8
8
|
# All rights reserved.
|
9
9
|
#
|
@@ -40,6 +40,16 @@ require 'thread'
|
|
40
40
|
module Blockenspiel
|
41
41
|
|
42
42
|
|
43
|
+
# === Determine whether the mixin strategy is available
|
44
|
+
#
|
45
|
+
# Returns true if the mixin strategy is available on the current ruby
|
46
|
+
# platform. This will be false for most platforms.
|
47
|
+
|
48
|
+
def self.mixin_available?
|
49
|
+
!::Blockenspiel::Unmixer.const_defined?(:UNIMPLEMENTED)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
43
53
|
# === Invoke a given DSL
|
44
54
|
#
|
45
55
|
# This is the entry point for Blockenspiel. Call this function to invoke
|
@@ -135,20 +145,8 @@ module Blockenspiel
|
|
135
145
|
# The following values control the precise behavior of parameterless
|
136
146
|
# blocks. These are values for the <tt>:parameterless</tt> option.
|
137
147
|
#
|
138
|
-
# [<tt>:mixin</tt>]
|
139
|
-
# This is the default behavior. DSL methods from the target are
|
140
|
-
# temporarily overlayed on the caller's +self+ object, but +self+ still
|
141
|
-
# points to the same object, so the helper methods and instance
|
142
|
-
# variables from the caller's closure remain available. The DSL methods
|
143
|
-
# are removed when the block completes.
|
144
|
-
# [<tt>:instance</tt>]
|
145
|
-
# This behavior actually changes +self+ to the target object using
|
146
|
-
# <tt>instance_eval</tt>. Thus, the caller loses access to its own
|
147
|
-
# helper methods and instance variables, and instead gains access to the
|
148
|
-
# target object's instance variables. The target object's methods are
|
149
|
-
# not modified: this behavior does not apply any DSL method changes
|
150
|
-
# specified using <tt>dsl_method</tt> directives.
|
151
148
|
# [<tt>:proxy</tt>]
|
149
|
+
# This is the default behavior for parameterless blocks.
|
152
150
|
# This behavior changes +self+ to a proxy object created by applying the
|
153
151
|
# DSL methods to an empty object, whose <tt>method_missing</tt> points
|
154
152
|
# back at the block's context. This behavior is a compromise between
|
@@ -159,6 +157,19 @@ module Blockenspiel
|
|
159
157
|
# object's instance variables are not available (and thus cannot be
|
160
158
|
# clobbered) in the block, and the transformations specified by
|
161
159
|
# <tt>dsl_method</tt> directives are honored.
|
160
|
+
# [<tt>:instance</tt>]
|
161
|
+
# This behavior changes +self+ directly to the target object using
|
162
|
+
# <tt>instance_eval</tt>. Thus, the caller loses access to its own
|
163
|
+
# helper methods and instance variables, and instead gains access to the
|
164
|
+
# target object's instance variables. The target object's methods are
|
165
|
+
# not modified: this behavior does not apply any DSL method changes
|
166
|
+
# specified using <tt>dsl_method</tt> directives.
|
167
|
+
# [<tt>:mixin</tt>]
|
168
|
+
# This behavior is not available on all ruby platforms. DSL methods from
|
169
|
+
# the target are temporarily overlayed on the caller's +self+ object, but
|
170
|
+
# +self+ still points to the same object. Thus the helper methods and
|
171
|
+
# instance variables from the caller's closure remain available. The DSL
|
172
|
+
# methods are removed when the block completes.
|
162
173
|
#
|
163
174
|
# === String DSL options
|
164
175
|
#
|
@@ -328,7 +339,7 @@ module Blockenspiel
|
|
328
339
|
end
|
329
340
|
|
330
341
|
# Execute the DSL using the proxy method.
|
331
|
-
_execute_dsl(
|
342
|
+
_execute_dsl(false, nil, eval_str_, target_, file_, line_)
|
332
343
|
end
|
333
344
|
|
334
345
|
|
@@ -368,7 +379,7 @@ module Blockenspiel
|
|
368
379
|
end
|
369
380
|
|
370
381
|
# Execute the DSL
|
371
|
-
_execute_dsl(parameterless_ == :
|
382
|
+
_execute_dsl(parameterless_ == :mixin, block_, nil, target_, nil, nil)
|
372
383
|
end
|
373
384
|
|
374
385
|
|
@@ -379,6 +390,10 @@ module Blockenspiel
|
|
379
390
|
|
380
391
|
class ProxyDelegator # :nodoc:
|
381
392
|
|
393
|
+
def initialize(delegate_)
|
394
|
+
@_blockenspiel_delegate = delegate_
|
395
|
+
end
|
396
|
+
|
382
397
|
def method_missing(symbol_, *params_, &block_)
|
383
398
|
::Blockenspiel._proxy_dispatch(self, symbol_, params_, block_)
|
384
399
|
end
|
@@ -399,7 +414,7 @@ module Blockenspiel
|
|
399
414
|
# This is the "meat" of Blockenspiel, implementing both the proxy and
|
400
415
|
# mixin methods.
|
401
416
|
|
402
|
-
def self._execute_dsl(
|
417
|
+
def self._execute_dsl(use_mixin_method_, block_, eval_str_, target_, file_, line_) # :nodoc:
|
403
418
|
# Get the module of dsl methods
|
404
419
|
mod_ = target_.class._get_blockenspiel_module rescue nil
|
405
420
|
unless mod_
|
@@ -409,36 +424,7 @@ module Blockenspiel
|
|
409
424
|
# Get the block's calling context object
|
410
425
|
context_object_ = block_ ? ::Kernel.eval('self', block_.binding) : nil
|
411
426
|
|
412
|
-
if
|
413
|
-
|
414
|
-
# Create proxy object
|
415
|
-
proxy_ = ::Blockenspiel::ProxyDelegator.new
|
416
|
-
proxy_.extend(mod_)
|
417
|
-
|
418
|
-
# Store the target and proxy object so dispatchers can get them
|
419
|
-
proxy_delegator_key_ = proxy_.object_id
|
420
|
-
target_stack_key_ = _current_context_id(proxy_)
|
421
|
-
@_proxy_delegators[proxy_delegator_key_] = context_object_ if context_object_
|
422
|
-
@_target_stacks[target_stack_key_] = [target_]
|
423
|
-
|
424
|
-
begin
|
425
|
-
|
426
|
-
# Evaluate with the proxy as self
|
427
|
-
if block_
|
428
|
-
return proxy_.instance_eval(&block_)
|
429
|
-
else
|
430
|
-
return proxy_.instance_eval(eval_str_, file_, line_)
|
431
|
-
end
|
432
|
-
|
433
|
-
ensure
|
434
|
-
|
435
|
-
# Clean up the dispatcher information
|
436
|
-
@_proxy_delegators.delete(proxy_delegator_key_) if context_object_
|
437
|
-
@_target_stacks.delete(target_stack_key_)
|
438
|
-
|
439
|
-
end
|
440
|
-
|
441
|
-
else
|
427
|
+
if use_mixin_method_
|
442
428
|
|
443
429
|
# Create hash keys
|
444
430
|
mixin_count_key_ = [context_object_.object_id, mod_.object_id]
|
@@ -486,6 +472,32 @@ module Blockenspiel
|
|
486
472
|
|
487
473
|
end
|
488
474
|
|
475
|
+
else
|
476
|
+
|
477
|
+
# Create proxy object
|
478
|
+
proxy_ = ::Blockenspiel::ProxyDelegator.new(context_object_)
|
479
|
+
proxy_.extend(mod_)
|
480
|
+
|
481
|
+
# Store the target object so the dispatcher can get it
|
482
|
+
target_stack_key_ = _current_context_id(proxy_)
|
483
|
+
@_target_stacks[target_stack_key_] = [target_]
|
484
|
+
|
485
|
+
begin
|
486
|
+
|
487
|
+
# Evaluate with the proxy as self
|
488
|
+
if block_
|
489
|
+
return proxy_.instance_eval(&block_)
|
490
|
+
else
|
491
|
+
return proxy_.instance_eval(eval_str_, file_, line_)
|
492
|
+
end
|
493
|
+
|
494
|
+
ensure
|
495
|
+
|
496
|
+
# Clean up the dispatcher information
|
497
|
+
@_target_stacks.delete(target_stack_key_)
|
498
|
+
|
499
|
+
end
|
500
|
+
|
489
501
|
end
|
490
502
|
end
|
491
503
|
|
@@ -513,7 +525,7 @@ module Blockenspiel
|
|
513
525
|
# We look up the context object, and call the given method on that object.
|
514
526
|
|
515
527
|
def self._proxy_dispatch(proxy_, name_, params_, block_) # :nodoc:
|
516
|
-
delegate_ =
|
528
|
+
delegate_ = proxy_.instance_variable_get(:@_blockenspiel_delegate)
|
517
529
|
if delegate_
|
518
530
|
delegate_.send(name_, *params_, &block_)
|
519
531
|
else
|