blockenspiel 0.2.2-java → 0.3.0-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.
@@ -81,11 +81,13 @@ module Blockenspiel
81
81
 
82
82
  module DSLSetupMethods
83
83
 
84
+
85
+ # :stopdoc:
86
+
84
87
  # Called when DSLSetupMethods extends a class.
85
88
  # This sets up the current class, and adds a hook that causes
86
- # any subclass of the current class to also be set up.
89
+ # any subclass of the current class also to be set up.
87
90
 
88
- # :stopdoc:
89
91
  def self.extended(klass_)
90
92
  unless klass_.instance_variable_defined?(:@_blockenspiel_module)
91
93
  _setup_class(klass_)
@@ -95,6 +97,7 @@ module Blockenspiel
95
97
  end
96
98
  end
97
99
  end
100
+
98
101
  # :startdoc:
99
102
 
100
103
 
@@ -175,12 +178,7 @@ module Blockenspiel
175
178
  end
176
179
  @_blockenspiel_methods[name_] = delegate_
177
180
  unless @_blockenspiel_module.public_method_defined?(name_)
178
- @_blockenspiel_module.module_eval("
179
- def #{name_}(*params_, &block_)
180
- val_ = ::Blockenspiel._target_dispatch(self, :#{name_}, params_, block_)
181
- val_ == ::Blockenspiel::TARGET_MISMATCH ? super(*params_, &block_) : val_
182
- end
183
- ")
181
+ @_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")
184
182
  end
185
183
  end
186
184
 
@@ -229,6 +227,91 @@ module Blockenspiel
229
227
  end
230
228
  end
231
229
 
230
+
231
+ # A DSL-friendly attr_accessor.
232
+ #
233
+ # This creates the usual "name" and "name=" methods in the current
234
+ # class that can be used in the usual way. However, its implementation
235
+ # of the "name" method (the getter) also takes an optional parameter
236
+ # that causes it to behave as a setter. This is done because the usual
237
+ # setter syntax cannot be used in a parameterless block, since it is
238
+ # syntactically indistinguishable from a local variable assignment.
239
+ # The "name" method is exposed as a dsl_method.
240
+ #
241
+ # For example:
242
+ #
243
+ # dsl_attr_accessor :foo
244
+ #
245
+ # enables the following:
246
+ #
247
+ # my_block do |param|
248
+ # param.foo = 1 # Usual setter syntax works
249
+ # param.foo 2 # Alternate setter syntax also works
250
+ # puts param.foo # Usual getter syntax still works
251
+ # end
252
+ #
253
+ # my_block do
254
+ # # foo = 1 # Usual setter syntax does NOT work since it
255
+ # # looks like a local variable assignment
256
+ # foo 2 # Alternate setter syntax does work
257
+ # puts foo # Usual getter syntax still works
258
+ # end
259
+
260
+ def dsl_attr_accessor(*names_)
261
+ names_.each do |name_|
262
+ unless name_.kind_of?(::String) || name_.kind_of?(::Symbol)
263
+ raise ::TypeError, "#{name_.inspect} is not a symbol"
264
+ end
265
+ unless name_.to_s =~ /^[_a-zA-Z]\w+$/
266
+ raise ::NameError, "invalid attribute name #{name_.inspect}"
267
+ end
268
+ module_eval("def #{name_}(value_=::Blockenspiel::NO_VALUE); ::Blockenspiel::NO_VALUE.equal?(value_) ? @#{name_} : @#{name_} = value_; end\n")
269
+ alias_method("#{name_}=", name_)
270
+ dsl_method(name_)
271
+ end
272
+ end
273
+
274
+
275
+ # A DSL-friendly attr_writer.
276
+ #
277
+ # This creates the usual "name=" method in the current class that can
278
+ # be used in the usual way. However, it also creates the method "name",
279
+ # which also functions as a setter (but not a getter). This is done
280
+ # because the usual setter syntax cannot be used in a parameterless
281
+ # block, since it is syntactically indistinguishable from a local
282
+ # variable assignment. The "name" method is exposed as a dsl_method.
283
+ #
284
+ # For example:
285
+ #
286
+ # dsl_attr_writer :foo
287
+ #
288
+ # is functionally equivalent to:
289
+ #
290
+ # attr_writer :foo
291
+ # alias_method :foo, :foo=
292
+ # dsl_method :foo
293
+ #
294
+ # which enables the following:
295
+ #
296
+ # my_block do |param|
297
+ # param.foo = 1 # Usual setter syntax works
298
+ # param.foo 2 # Alternate setter syntax also works
299
+ # end
300
+ # my_block do
301
+ # # foo = 1 # Usual setter syntax does NOT work since it
302
+ # # looks like a local variable assignment
303
+ # foo(2) # Alternate setter syntax does work
304
+ # end
305
+
306
+ def dsl_attr_writer(*names_)
307
+ names_.each do |name_|
308
+ attr_writer(name_)
309
+ alias_method(name_, "#{name_}=")
310
+ dsl_method(name_)
311
+ end
312
+ end
313
+
314
+
232
315
  end
233
316
 
234
317
 
@@ -306,11 +389,7 @@ module Blockenspiel
306
389
 
307
390
  def self._add_methodinfo(name_, block_, yields_)
308
391
  (@_blockenspiel_methodinfo ||= ::Hash.new)[name_] = [block_, yields_]
309
- module_eval("
310
- def #{name_}(*params_, &block_)
311
- self.class._invoke_methodinfo(:#{name_}, params_, block_)
312
- end
313
- ")
392
+ module_eval("def #{name_}(*params_, &block_); self.class._invoke_methodinfo(:#{name_}, params_, block_); end\n")
314
393
  end
315
394
 
316
395
 
@@ -324,7 +403,7 @@ module Blockenspiel
324
403
  when :last
325
404
  params_.push(block_)
326
405
  end
327
- info_[0].call(*params_)
406
+ info_[0].call(*params_, &block_)
328
407
  end
329
408
 
330
409
  end
@@ -348,24 +427,60 @@ module Blockenspiel
348
427
  # === Declare a DSL method.
349
428
  #
350
429
  # This call creates a method that can be called from the DSL block.
351
- # Provide a name for the method, and a block defining the method's
352
- # implementation. You may also provided a list of options as follows:
353
- #
354
- # The <tt>:block</tt> option controls how the generated method reports
355
- # any block provided by the caller. If set to +false+ or not given, any
356
- # caller-provided block is ignored. If set to <tt>:first</tt>, the
357
- # block is _prepended_ (as a +Proc+ object) to the parameters passed to
358
- # the method's implementing block. If set to <tt>:last</tt>, the block
359
- # is _appended_. In either case, if the caller does not provide a block,
360
- # a value of +nil+ is pre- or appended to the parameter list. A value of
361
- # +true+ is equivalent to <tt>:first</tt>.
362
- # (This is a workaround for the fact that blocks cannot themselves take
363
- # block parameters in Ruby 1.8.)
430
+ # Provide a name for the method, a block defining the method's
431
+ # implementation, and an optional hash of options.
364
432
  #
433
+ # By default, a method of the same name is also made available to
434
+ # parameterless blocks. To change the name of the parameterless method,
435
+ # provide its name as the value of the <tt>:dsl_method</tt> option.
436
+ # To disable this method for parameterless blocks, set the
437
+ # <tt>:dsl_method</tt> option to +false+.
438
+ #
439
+ # The <tt>:mixin</tt> option is a deprecated alias for
440
+ # <tt>:dsl_method</tt>.
441
+ #
442
+ # === Warning about the +return+ keyword
443
+ #
444
+ # Because you are implementing your method using a block, remember the
445
+ # distinction between <tt>Proc.new</tt> and +lambda+. Invoking +return+
446
+ # from the former does not return from the block, but returns from the
447
+ # surrounding method scope. Since normal blocks passed to methods are
448
+ # of the former type, be very careful about using the +return+ keyword:
449
+ #
450
+ # add_method(:foo) do |param|
451
+ # puts "foo called with parameter "+param.inspect
452
+ # return "a return value" # DOESN'T WORK LIKE YOU EXPECT!
453
+ # end
454
+ #
455
+ # To return a value from the method you are creating, set the evaluation
456
+ # value at the end of the block:
457
+ #
458
+ # add_method(:foo) do |param|
459
+ # puts "foo called with parameter "+param.inspect
460
+ # "a return value" # Returns from method foo
461
+ # end
462
+ #
463
+ # If you must use the +return+ keyword, create your block as a lambda
464
+ # as in this example:
465
+ #
466
+ # code = lambda do |param|
467
+ # puts "foo called with parameter "+param.inspect
468
+ # return "a return value" # Returns from method foo
469
+ # end
470
+ # add_method(:foo, &code)
471
+ #
472
+ # === Accepting a block argument
473
+ #
474
+ # If you want your method to take a block, you have several options
475
+ # depending on your Ruby version. If you are running the standard Matz
476
+ # Ruby interpreter (MRI) version 1.8.7 or later (including 1.9.x), you
477
+ # can use the standard "&" block argument notation to receive the block.
478
+ # Note that you must call the passed block using the +call+ method since
479
+ # Ruby doesn't support invoking such a block with +yield+.
365
480
  # For example, to create a method named "foo" that takes one parameter
366
481
  # and a block, do this:
367
482
  #
368
- # add_method(:foo, :block => :first) do |block, param|
483
+ # add_method(:foo) do |param, &block|
369
484
  # puts "foo called with parameter "+param.inspect
370
485
  # puts "the block returned "+block.call.inspect
371
486
  # end
@@ -374,18 +489,32 @@ module Blockenspiel
374
489
  #
375
490
  # foo("hello"){ "a value" }
376
491
  #
377
- # By default, a method of the same name is also made available to
378
- # parameterless blocks. To change the name of the parameterless method,
379
- # provide its name as the value of the <tt>:dsl_method</tt> option.
380
- # To disable this method for parameterless blocks, set the
381
- # <tt>:dsl_method</tt> option to +false+.
492
+ # If you are using MRI 1.8.6, however, the parser does not support
493
+ # passing a block argument to a block. Oddly, the current version of
494
+ # JRuby (version 1.4.0 as of this writing) also does not support this
495
+ # syntax, though it claims MRI 1.8.7 compatibility. (See bug JRUBY-4180
496
+ # to track this issue.) If your Ruby interpreter doesn't support the
497
+ # standard way to create a method that takes a block, Blockenspiel
498
+ # provides an alternative in the form of the <tt>:block</tt> option.
499
+ # This option causes blocks provided by the caller to be included in
500
+ # the normal parameter list to your method, instead of as a block
501
+ # parameter. It can be set to <tt>:first</tt> or <tt>:last</tt> to
502
+ # prepend or append, respectively, the block (as a +Proc+ object) to
503
+ # the parameter list. If the caller does not include a block when
504
+ # calling your DSL method, nil is prepended/appended. For example:
382
505
  #
383
- # For historical reasons, the <tt>:mixin</tt> option is an alias for
384
- # <tt>:dsl_method</tt>. However, its use is deprecated.
506
+ # add_method(:foo, :block => :last) do |param, block|
507
+ # puts "foo called with parameter "+param.inspect
508
+ # if block
509
+ # puts "the block returned "+block.call.inspect
510
+ # else
511
+ # puts "no block passed"
512
+ # end
513
+ # end
385
514
  #
386
- # The <tt>:receive_block</tt> option is also supported for historical
387
- # reasons, but its use is deprecated. Setting <tt>:receive_block</tt> to
388
- # +true+ is equivalent to setting <tt>:block</tt> to <tt>:last</tt>.
515
+ # The <tt>:receive_block</tt> option is a deprecated alternative.
516
+ # Setting <tt>:receive_block => true</tt> is currently equivalent to
517
+ # setting <tt>:block => :last</tt>.
389
518
 
390
519
  def add_method(name_, opts_={}, &block_)
391
520
  receive_block_ = opts_[:receive_block] ? :last : opts_[:block]
@@ -402,7 +531,7 @@ module Blockenspiel
402
531
 
403
532
 
404
533
  # :stopdoc:
405
- TARGET_MISMATCH = ::Object.new
534
+ NO_VALUE = ::Object.new
406
535
  # :startdoc:
407
536
 
408
537
  @_target_stacks = ::Hash.new
@@ -411,18 +540,37 @@ module Blockenspiel
411
540
  @_mutex = ::Mutex.new
412
541
 
413
542
 
414
- # === Invoke a given block.
543
+ # === Invoke a given block
415
544
  #
416
545
  # This is the meat of Blockenspiel. Call this function to invoke a block
417
546
  # provided by the user of your API.
418
547
  #
548
+ # For example, if you want users of your API to be able to do this:
549
+ #
550
+ # call_dsl do
551
+ # foo(1)
552
+ # bar(2)
553
+ # end
554
+ #
555
+ # Then you should implement <tt>call_dsl</tt> like this:
556
+ #
557
+ # def call_dsl(&block)
558
+ # my_dsl = create_block_implementation
559
+ # Blockenspiel.invoke(block, my_dsl)
560
+ # do_something_with(my_dsl)
561
+ # end
562
+ #
563
+ # In the above, <tt>create_block_implementation</tt> is a placeholder that
564
+ # returns an instance of your DSL methods class. This class includes the
565
+ # Blockenspiel::DSL module and defines the DSL methods +foo+ and +bar+.
566
+ #
419
567
  # Normally, this method will check the block's arity to see whether it
420
568
  # takes a parameter. If so, it will pass the given target to the block.
421
569
  # If the block takes no parameter, and the given target is an instance of
422
570
  # a class with DSL capability, the DSL methods are made available on the
423
571
  # caller's self object so they may be called without a block parameter.
424
572
  #
425
- # Recognized options include:
573
+ # === Recognized options
426
574
  #
427
575
  # <tt>:parameterless</tt>::
428
576
  # If set to false, disables parameterless blocks and always attempts to
@@ -471,7 +619,7 @@ module Blockenspiel
471
619
  # add_method(:set_foo) do |value|
472
620
  # my_foo = value
473
621
  # end
474
- # add_method(:set_things_from_block, :block => :last) do |value,blk|
622
+ # add_method(:set_things_from_block) do |value, &blk|
475
623
  # my_foo = value
476
624
  # my_bar = blk.call
477
625
  # end
@@ -495,10 +643,10 @@ module Blockenspiel
495
643
  #
496
644
  # The obvious advantage of using dynamic object generation is that you are
497
645
  # creating methods using closures, which provides the opportunity to, for
498
- # example, modify closure variables such as my_foo. This is more difficult
499
- # to do when you create a target class since its methods do not have access
500
- # to outside data. Hence, in the above example, we hand-waved, assuming the
501
- # existence of some method called "set_my_foo_from".
646
+ # example, modify closure local variables such as my_foo. This is more
647
+ # difficult to do when you create a target class since its methods do not
648
+ # have access to outside data. Hence, in the above example, we hand-waved,
649
+ # assuming the existence of some method called "set_my_foo_from".
502
650
  #
503
651
  # The disadvantage is performance. If you dynamically generate a target
504
652
  # object, it involves parsing and creating a new class whenever it is
@@ -643,11 +791,11 @@ module Blockenspiel
643
791
  # This implements the mapping between DSL module methods and target object methods.
644
792
  # We look up the current target object based on the current thread.
645
793
  # Then we attempt to call the given method on that object.
646
- # If we can't find an appropriate method to call, return the special value TARGET_MISMATCH.
794
+ # If we can't find an appropriate method to call, return the special value NO_VALUE.
647
795
 
648
796
  def self._target_dispatch(object_, name_, params_, block_) # :nodoc:
649
797
  target_stack_ = @_target_stacks[[::Thread.current.object_id, object_.object_id]]
650
- return ::Blockenspiel::TARGET_MISMATCH unless target_stack_
798
+ return ::Blockenspiel::NO_VALUE unless target_stack_
651
799
  target_stack_.reverse_each do |target_|
652
800
  target_class_ = target_.class
653
801
  delegate_ = target_class_._get_blockenspiel_delegate(name_)
@@ -655,7 +803,7 @@ module Blockenspiel
655
803
  return target_.send(delegate_, *params_, &block_)
656
804
  end
657
805
  end
658
- return ::Blockenspiel::TARGET_MISMATCH
806
+ return ::Blockenspiel::NO_VALUE
659
807
  end
660
808
 
661
809
 
@@ -37,6 +37,6 @@
37
37
  module Blockenspiel
38
38
 
39
39
  # Current gem version, as a frozen string.
40
- VERSION_STRING = '0.2.2'.freeze
40
+ VERSION_STRING = '0.3.0'.freeze
41
41
 
42
42
  end
Binary file
data/tests/tc_basic.rb CHANGED
@@ -74,7 +74,7 @@ module Blockenspiel
74
74
  # * Asserts that the specified target object does in fact receive the block messages.
75
75
 
76
76
  def test_basic_param
77
- block_ = proc do |t_|
77
+ block_ = ::Proc.new do |t_|
78
78
  t_.set_value(:a, 1)
79
79
  t_.set_value_by_block(:b){ 2 }
80
80
  assert(!self.respond_to?(:set_value))
@@ -94,7 +94,7 @@ module Blockenspiel
94
94
  # * Asserts that the specified target object still receives the messages.
95
95
 
96
96
  def test_basic_mixin
97
- block_ = proc do
97
+ block_ = ::Proc.new do
98
98
  set_value(:a, 1)
99
99
  set_value_by_block(:b){ 2 }
100
100
  end
@@ -113,7 +113,7 @@ module Blockenspiel
113
113
  # * Asserts that receivers with blocks are handled properly.
114
114
 
115
115
  def test_basic_builder
116
- block_ = proc do
116
+ block_ = ::Proc.new do
117
117
  set_value(:a, 1)
118
118
  set_value_by_block(:b){ 2 }
119
119
  end
@@ -89,7 +89,7 @@ module Blockenspiel
89
89
  hash_ = ::Hash.new
90
90
  context_self_ = self
91
91
  @my_instance_variable_test = :hello
92
- block_ = proc do
92
+ block_ = ::Proc.new do
93
93
  set_value1('a', 1)
94
94
  set_value2('b'){ 2 }
95
95
  set_value3('c', 3)
@@ -116,7 +116,7 @@ module Blockenspiel
116
116
  hash_ = ::Hash.new
117
117
  context_self_ = self
118
118
  @my_instance_variable_test = :hello
119
- block_ = proc do
119
+ block_ = ::Proc.new do
120
120
  set_value1('a', 1)
121
121
  set_value2('b'){ 2 }
122
122
  set_value3_dslversion('c', 3)
@@ -140,13 +140,13 @@ module Blockenspiel
140
140
 
141
141
  def test_disable_parameterless
142
142
  hash_ = ::Hash.new
143
- block1_ = proc do ||
143
+ block1_ = ::Proc.new do ||
144
144
  set_value1('a', 1)
145
145
  end
146
- block2_ = proc do |target_|
146
+ block2_ = ::Proc.new do |target_|
147
147
  target_.set_value1('b', 2)
148
148
  end
149
- block3_ = proc do
149
+ block3_ = ::Proc.new do
150
150
  set_value1('c', 3)
151
151
  end
152
152
  assert_raise(::Blockenspiel::BlockParameterError) do
@@ -167,13 +167,13 @@ module Blockenspiel
167
167
 
168
168
  def test_disable_parametered
169
169
  hash_ = ::Hash.new
170
- block1_ = proc do ||
170
+ block1_ = ::Proc.new do ||
171
171
  set_value1('a', 1)
172
172
  end
173
- block2_ = proc do |target_|
173
+ block2_ = ::Proc.new do |target_|
174
174
  target_.set_value1('b', 2)
175
175
  end
176
- block3_ = proc do
176
+ block3_ = ::Proc.new do
177
177
  set_value1('c', 3)
178
178
  end
179
179
  ::Blockenspiel.invoke(block1_, Target1.new(hash_), :parameter => false)
@@ -0,0 +1,134 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Blockenspiel dsl attribute tests
4
+ #
5
+ # This file contains tests for the dsl attribute directives.
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 TestDSLAttrs < ::Test::Unit::TestCase # :nodoc:
47
+
48
+
49
+ class WriterTarget < ::Blockenspiel::Base
50
+
51
+ dsl_attr_writer(:attr1, :attr2)
52
+
53
+ end
54
+
55
+
56
+ class AccessorTarget < ::Blockenspiel::Base
57
+
58
+ dsl_attr_accessor(:attr1, :attr2)
59
+
60
+ end
61
+
62
+
63
+ # Test dsl attr writer in a parametered block
64
+ #
65
+ # * Asserts that the standard setter syntax works
66
+ # * Asserts that the alternate setter syntax works
67
+
68
+ def test_writer_parametered
69
+ block_ = ::Proc.new do |param_|
70
+ param_.attr1 = 1
71
+ assert_equal(2, param_.attr2(2))
72
+ end
73
+ target_ = WriterTarget.new
74
+ ::Blockenspiel.invoke(block_, target_)
75
+ assert_equal(1, target_.instance_variable_get(:@attr1))
76
+ assert_equal(2, target_.instance_variable_get(:@attr2))
77
+ end
78
+
79
+
80
+ # Test dsl attr writer in a parameterless block
81
+ #
82
+ # * Asserts that the alternate setter syntax works
83
+
84
+ def test_writer_parameterless
85
+ block_ = ::Proc.new do
86
+ assert_equal(2, attr2(2))
87
+ end
88
+ target_ = WriterTarget.new
89
+ ::Blockenspiel.invoke(block_, target_)
90
+ assert_nil(target_.instance_variable_get(:@attr1))
91
+ assert_equal(2, target_.instance_variable_get(:@attr2))
92
+ end
93
+
94
+
95
+ # Test dsl attr accessor in a parametered block
96
+ #
97
+ # * Asserts that the standard setter syntax works
98
+ # * Asserts that the alternate setter syntax works
99
+ # * Asserts that the getter syntax works
100
+
101
+ def _test_accessor_parametered
102
+ block_ = ::Proc.new do |param_|
103
+ param_.attr1 = 1
104
+ assert_equal(2, param_.attr2(2))
105
+ assert_equal(2, param_.attr2)
106
+ end
107
+ target_ = AccessorTarget.new
108
+ ::Blockenspiel.invoke(block_, target_)
109
+ assert_equal(1, target_.instance_variable_get(:@attr1))
110
+ assert_equal(2, target_.instance_variable_get(:@attr2))
111
+ end
112
+
113
+
114
+ # Test dsl attr accessor in a parameterless block
115
+ #
116
+ # * Asserts that the alternate setter syntax works
117
+ # * Asserts that the getter syntax works
118
+
119
+ def test_accessor_parameterless
120
+ block_ = ::Proc.new do
121
+ assert_equal(2, attr2(2))
122
+ assert_equal(2, attr2)
123
+ end
124
+ target_ = AccessorTarget.new
125
+ ::Blockenspiel.invoke(block_, target_)
126
+ assert_nil(target_.instance_variable_get(:@attr1))
127
+ assert_equal(2, target_.instance_variable_get(:@attr2))
128
+ end
129
+
130
+
131
+ end
132
+
133
+ end
134
+ end
@@ -203,7 +203,7 @@ module Blockenspiel
203
203
 
204
204
  def test_default_setting
205
205
  hash_ = ::Hash.new
206
- block_ = proc do
206
+ block_ = ::Proc.new do
207
207
  set_value1('a', 1)
208
208
  set_value2('b'){ 2 }
209
209
  assert_raise(::NoMethodError){ _set_value3('c', 3) }
@@ -223,7 +223,7 @@ module Blockenspiel
223
223
 
224
224
  def test_onoff_switching
225
225
  hash_ = ::Hash.new
226
- block_ = proc do
226
+ block_ = ::Proc.new do
227
227
  assert_raise(::NoMethodError){ _set_value1('a', 1) }
228
228
  set_value2('b'){ 2 }
229
229
  _set_value3('c', 3)
@@ -242,7 +242,7 @@ module Blockenspiel
242
242
 
243
243
  def test_explicit_add
244
244
  hash_ = ::Hash.new
245
- block_ = proc do
245
+ block_ = ::Proc.new do
246
246
  set_value1('a', 1)
247
247
  assert_raise(::NoMethodError){ set_value2('b'){ 2 } }
248
248
  renamed_set_value2('c'){ 3 }
@@ -263,7 +263,7 @@ module Blockenspiel
263
263
 
264
264
  def test_explicit_removing
265
265
  hash_ = ::Hash.new
266
- block_ = proc do
266
+ block_ = ::Proc.new do
267
267
  assert_raise(::NoMethodError){ set_value1('a', 1) }
268
268
  assert_raise(::NoMethodError){ set_value2('b'){ 2 } }
269
269
  renamed_set_value2('c'){ 3 }
@@ -282,7 +282,7 @@ module Blockenspiel
282
282
 
283
283
  def test_subclassing
284
284
  hash_ = ::Hash.new
285
- block_ = proc do
285
+ block_ = ::Proc.new do
286
286
  set_value1('a', 1)
287
287
  set_value2('b'){ 2 }
288
288
  assert_raise(::NoMethodError){ set_value3('c', 3) }
@@ -307,7 +307,7 @@ module Blockenspiel
307
307
 
308
308
  def test_multiple_dsl_methods
309
309
  hash_ = ::Hash.new
310
- block_ = proc do
310
+ block_ = ::Proc.new do
311
311
  set_value1('a', 1)
312
312
  renamed_set_value2('b'){ 2 }
313
313
  assert_raise(::NoMethodError){ set_value2('c', 3) }