qualitysmith_extensions 0.0.20 → 0.0.24

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.
@@ -5,7 +5,10 @@
5
5
  # Submit to Facets?:: Yes!
6
6
  # Developer notes::
7
7
  # * Is it thread-safe?? Probably not, as it stands...
8
- # But the whole thing that prompted me to create a guard method in the first place was to try to avoid a deadlock that was caused by recursively calling a method with a synchronize in it. So I'm not even sure if it's possible to make it thread-safe?
8
+ # But the whole thing that prompted me to create a guard method in the first place was to try to avoid a deadlock that was
9
+ # caused by recursively calling a method with a synchronize in it (in other words, someone else's attempt at thread-safety
10
+ # resulted in me getting into a deadlock, which is why I wrote this method to begin with). So I'm not even sure if it's
11
+ # possible to make it thread-safe?
9
12
  #++
10
13
 
11
14
  require 'rubygems'
@@ -16,23 +19,78 @@ require 'qualitysmith_extensions/symbol/match'
16
19
 
17
20
 
18
21
  class Module
19
- def guard_method(method_name, guard_variable)
22
+ # A guard method (by this definition anyway) is a method that sets a flag, executes a block, and then returns the flag to its
23
+ # previous value. It ensures that the flag is set during the execution of the block.
24
+ #
25
+ # In the simplest case, you'd use it like this:
26
+ # class A
27
+ # guard_method :disable_stupid_stuff!, :@stupid_stuff_disabled
28
+ # end
29
+ # a = A.new
30
+ # a.disable_stupid_stuff! do # Causes @stupid_stuff_disabled to be set to true
31
+ # # Section of code during which you don't want any stupid stuff to happen
32
+ # end # Causes @stupid_stuff_disabled to be set back to false
33
+ # # Okay, a, you can resume doing stupid stuff again...
34
+ #
35
+ # If you also want a guard method that *disables* the flag rather than *enabling* it, simply pass in the desired name of this
36
+ # "unguard" method as the value of the +unguard_method_name+ argument.
37
+ # class A
38
+ # guard_method :guard_the_fruit!, :@guarding_the_fruit, :stop_guarding_the_fruit!
39
+ # end
40
+ #
41
+ # Examples of unguard methods:
42
+ # mguard_method :color_on!, :@@color_enabled, :color_off!
43
+ # mguard_method :without_benchmarking, :@@benchmarking_disabled, :with_benchmarking
44
+ #
45
+ # These calls can be nested however you wish:
46
+ # a.guard_the_fruit! do
47
+ # a.stop_guarding_the_fruit! do
48
+ # assert_equal false, a.guarding_the_fruit?
49
+ # end
50
+ # assert_equal true, a.guarding_the_fruit?
51
+ # end
52
+ #
53
+ # You can also use the guard methods as normal flag setter/clearer methods by simply not passing a block to it. Hence
54
+ # a.guard_the_fruit!
55
+ # will simply set @guarding_the_fruit to true, and
56
+ # a.stop_guarding_the_fruit!
57
+ # will set @guarding_the_fruit to false.
58
+ #
59
+ def guard_method(guard_method_name, guard_variable, unguard_method_name = nil)
20
60
  raise ArgumentError.new("Expected an instance variable name but got #{guard_variable}") if guard_variable !~ /^@([\w_]+)$/
21
61
  guard_variable.to_s =~ /^@([\w_]+)$/ # Why didn't the regexp above set $1 ??
22
62
  class_eval do
23
63
  attr_tester $1.to_sym
24
64
  end
25
65
  module_eval <<-End, __FILE__, __LINE__+1
26
- def #{method_name}(&block)
66
+ def #{guard_method_name}(new_value = nil, &block)
27
67
  old_guard_state, #{guard_variable} = #{guard_variable}, true
28
- returning = yield
29
- #{guard_variable} = old_guard_state
30
- returning
68
+ if block_given?
69
+ returning = yield
70
+ #{guard_variable} = old_guard_state
71
+ returning
72
+ end
73
+ end
74
+ End
75
+ module_eval <<-End, __FILE__, __LINE__+1 unless unguard_method_name.nil?
76
+ def #{unguard_method_name}(new_value = nil, &block)
77
+ old_guard_state, #{guard_variable} = #{guard_variable}, false
78
+ if block_given?
79
+ returning = yield
80
+ #{guard_variable} = old_guard_state
81
+ returning
82
+ end
31
83
  end
32
84
  End
33
85
  end
34
86
 
35
- def mguard_method(method_name, guard_variable)
87
+ # See the documentation for guard_method. mguard_method does the same thing, only it creates a _class_ (or _module_) method
88
+ # rather than an instance method and it uses a _class_ (or _module_) variable rather than an instance variable to store the
89
+ # guard state.
90
+ #
91
+ # Example:
92
+ # mguard_method :guard_the_fruit!, :@@guarding_the_fruit
93
+ def mguard_method(guard_method_name, guard_variable, unguard_method_name = nil)
36
94
  raise ArgumentError.new("Expected a class variable name but got #{guard_variable}") if guard_variable !~ /^@@[\w_]+$/
37
95
  guard_variable.to_s =~ /^@@([\w_]+)$/
38
96
  class_eval do
@@ -40,11 +98,25 @@ class Module
40
98
  end
41
99
  module_eval <<-End, __FILE__, __LINE__+1
42
100
  class << self
43
- def #{method_name}(&block)
101
+ def #{guard_method_name}(new_value = nil, &block)
44
102
  old_guard_state, #{guard_variable} = #{guard_variable}, true
45
- returning = yield
46
- #{guard_variable} = old_guard_state
47
- returning
103
+ if block_given?
104
+ returning = yield
105
+ #{guard_variable} = old_guard_state
106
+ returning
107
+ end
108
+ end
109
+ end
110
+ End
111
+ module_eval <<-End, __FILE__, __LINE__+1 unless unguard_method_name.nil?
112
+ class << self
113
+ def #{unguard_method_name}(new_value = nil, &block)
114
+ old_guard_state, #{guard_variable} = #{guard_variable}, false
115
+ if block_given?
116
+ returning = yield
117
+ #{guard_variable} = old_guard_state
118
+ returning
119
+ end
48
120
  end
49
121
  end
50
122
  End
@@ -61,7 +133,7 @@ end
61
133
  =begin test
62
134
  require 'test/unit'
63
135
 
64
- class GuardMethodTest < Test::Unit::TestCase
136
+ class GuardMethodTest_Simple < Test::Unit::TestCase
65
137
  class A
66
138
  guard_method :guard_the_fruit!, :@guarding_the_fruit
67
139
  end
@@ -89,7 +161,70 @@ class GuardMethodTest < Test::Unit::TestCase
89
161
  end
90
162
  end
91
163
 
92
- class MGuardMethodTest < Test::Unit::TestCase
164
+ class GuardMethodTest_WithUnguard < Test::Unit::TestCase
165
+ class A
166
+ guard_method :guard_the_fruit!, :@guarding_the_fruit, :stop_guarding_the_fruit!
167
+ end
168
+ def test_guard_method
169
+ a = A.new
170
+ assert_equal nil, a.guarding_the_fruit?
171
+ a.guard_the_fruit! do
172
+ a.guard_the_fruit! do
173
+ assert_equal true, a.guarding_the_fruit?
174
+
175
+ a.stop_guarding_the_fruit! do
176
+ assert_equal false, a.guarding_the_fruit?
177
+ a.guard_the_fruit! do
178
+ assert_equal true, a.guarding_the_fruit?
179
+ end
180
+ assert_equal false, a.guarding_the_fruit?
181
+ end
182
+
183
+ assert_equal true, a.guarding_the_fruit?
184
+ end
185
+ assert_equal true, a.guarding_the_fruit?
186
+ end
187
+ assert_equal nil, a.guarding_the_fruit?
188
+ end
189
+
190
+ def test_guard_method_with_simple_blockless_toggles
191
+ a = A.new
192
+ assert_equal nil, a.guarding_the_fruit?
193
+ a.guard_the_fruit!
194
+ assert_equal true, a.guarding_the_fruit?
195
+
196
+ a.stop_guarding_the_fruit! do
197
+ assert_equal false, a.guarding_the_fruit?
198
+ a.guard_the_fruit! do
199
+ assert_equal true, a.guarding_the_fruit?
200
+ a.stop_guarding_the_fruit!
201
+ assert_equal false, a.guarding_the_fruit?
202
+ a.guard_the_fruit!
203
+ assert_equal true, a.guarding_the_fruit?
204
+ end
205
+ assert_equal false, a.guarding_the_fruit?
206
+ end
207
+
208
+ assert_equal true, a.guarding_the_fruit?
209
+ end
210
+
211
+ def test_return_value
212
+ assert_equal nil, A.new.guard_the_fruit!
213
+ assert_equal nil, A.new.stop_guarding_the_fruit!
214
+ assert_equal 'special return value', A.new.guard_the_fruit! { 'special return value' }
215
+ assert_equal 'special return value', A.new.stop_guarding_the_fruit! { 'special return value' }
216
+ end
217
+ end
218
+
219
+ #---------------------------------------------------------------------------------------------------------------------------------
220
+ # Begin duplication
221
+ # The following TestCases are simply duplicates of the previous except that they test mguard_method rather than guard_method
222
+ # The main differenes/substitutions:
223
+ # * @@guarding_the_fruit, rather than @guarding_the_fruit
224
+ # * :'<,'>s/A.new/B/g
225
+ # * :'<,'>s/\<a\>/B/g
226
+
227
+ class MGuardMethodTest_Simple < Test::Unit::TestCase
93
228
  class B
94
229
  mguard_method :guard_the_fruit!, :@@guarding_the_fruit
95
230
  end
@@ -114,7 +249,61 @@ class MGuardMethodTest < Test::Unit::TestCase
114
249
  def test_return_value
115
250
  assert_equal 'special return value', B.guard_the_fruit! { 'special return value' }
116
251
  end
252
+ end
253
+
254
+ class MGuardMethodTest_WithUnguard < Test::Unit::TestCase
255
+ class B
256
+ mguard_method :guard_the_fruit!, :@@guarding_the_fruit, :stop_guarding_the_fruit!
257
+ end
258
+ def test_guard_method
259
+ assert_equal nil, B.guarding_the_fruit?
260
+ B.guard_the_fruit! do
261
+ B.guard_the_fruit! do
262
+ assert_equal true, B.guarding_the_fruit?
117
263
 
264
+ B.stop_guarding_the_fruit! do
265
+ assert_equal false, B.guarding_the_fruit?
266
+ B.guard_the_fruit! do
267
+ assert_equal true, B.guarding_the_fruit?
268
+ end
269
+ assert_equal false, B.guarding_the_fruit?
270
+ end
271
+
272
+ assert_equal true, B.guarding_the_fruit?
273
+ end
274
+ assert_equal true, B.guarding_the_fruit?
275
+ end
276
+ assert_equal nil, B.guarding_the_fruit?
277
+ end
278
+
279
+ def test_guard_method_with_simple_blockless_toggles
280
+ assert_equal nil, B.guarding_the_fruit?
281
+ B.guard_the_fruit!
282
+ assert_equal true, B.guarding_the_fruit?
283
+
284
+ B.stop_guarding_the_fruit! do
285
+ assert_equal false, B.guarding_the_fruit?
286
+ B.guard_the_fruit! do
287
+ assert_equal true, B.guarding_the_fruit?
288
+ B.stop_guarding_the_fruit!
289
+ assert_equal false, B.guarding_the_fruit?
290
+ B.guard_the_fruit!
291
+ assert_equal true, B.guarding_the_fruit?
292
+ end
293
+ assert_equal false, B.guarding_the_fruit?
294
+ end
295
+
296
+ assert_equal true, B.guarding_the_fruit?
297
+ end
298
+
299
+ def test_return_value
300
+ assert_equal nil, B.guard_the_fruit!
301
+ assert_equal nil, B.stop_guarding_the_fruit!
302
+ assert_equal 'special return value', B.guard_the_fruit! { 'special return value' }
303
+ assert_equal 'special return value', B.stop_guarding_the_fruit! { 'special return value' }
304
+ end
118
305
  end
306
+ # End duplication
307
+ #---------------------------------------------------------------------------------------------------------------------------------
119
308
  =end
120
309
 
@@ -0,0 +1,6 @@
1
+ # Idea:
2
+ # Allow using hashes:
3
+ # alias_method :code_review => :view_commits
4
+ # instead of
5
+ # alias_method :code_review, :view_commits
6
+ # because I always forget which argument becomes the argument for which
@@ -0,0 +1,46 @@
1
+ # Copied from ActiveSupport because I couldn't get the ones in Facets to work...
2
+
3
+ # Extends the module object with module and instance accessors for class attributes,
4
+ # just like the native attr* accessors for instance attributes.
5
+ class Module # :nodoc:
6
+ def mattr_reader(*syms)
7
+ syms.each do |sym|
8
+ class_eval(<<-EOS, __FILE__, __LINE__+1)
9
+ unless defined? @@#{sym}
10
+ @@#{sym} = nil
11
+ end
12
+
13
+ def self.#{sym}
14
+ @@#{sym}
15
+ end
16
+
17
+ def #{sym}
18
+ @@#{sym}
19
+ end
20
+ EOS
21
+ end
22
+ end
23
+
24
+ def mattr_writer(*syms)
25
+ syms.each do |sym|
26
+ class_eval(<<-EOS, __FILE__, __LINE__+1)
27
+ unless defined? @@#{sym}
28
+ @@#{sym} = nil
29
+ end
30
+
31
+ def self.#{sym}=(obj)
32
+ @@#{sym} = obj
33
+ end
34
+
35
+ def #{sym}=(obj)
36
+ @@#{sym} = obj
37
+ end
38
+ EOS
39
+ end
40
+ end
41
+
42
+ def mattr_accessor(*syms)
43
+ mattr_reader(*syms)
44
+ mattr_writer(*syms)
45
+ end
46
+ end
@@ -0,0 +1,334 @@
1
+ #--
2
+ # Author:: Thomas Sawyer, Tyler Rick
3
+ # Copyright:: Copyright (c) Thomas Sawyer, probably, since this is a derivative work
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes
6
+ # Developer notes::
7
+ # * Based on /usr/lib/ruby/gems/1.8/gems/facets-1.8.54/lib/facets/core/module/attr_tester.rb
8
+ # * Hey Thomas, don't you think Module#attr_tester should only create the read-only a? method and have another method that creates the writer (like there how we have attr_reader, _writer, and _accessor?) ? "tester" does not imply "setter" in my mind...
9
+ # * I'm going to rename this one to bool_attr_accessor, which calls both bool_attr_reader and bool_attr_writer
10
+ # * Then you also have the option to use bool_attr_reader and bool_attr_writer separately if you so desire.
11
+ # * Other changes made:
12
+ # * Changed it so that if you call a!(false) it would actually set @a to false rather than leaving it unchanged. (I assume that was a bug.)
13
+ #++
14
+
15
+
16
+ class Module
17
+
18
+ # This creates two methods for each given variable name. One is used to test
19
+ # the attribute and the other is used to set or toggle it.
20
+ #
21
+ # bool_attr_accessor :a
22
+ #
23
+ # is equivalent to
24
+ #
25
+ # def a?
26
+ # @a ? true : @a
27
+ # end
28
+ #
29
+ # def a!(switch=Exception)
30
+ # if switch == Exception
31
+ # @a = !@a
32
+ # else
33
+ # @a = switch ? true : false
34
+ # self
35
+ # end
36
+ # end
37
+ #
38
+ # Examples:
39
+ # x = Klass.new
40
+ # x.a! true # sets @a to true
41
+ # x.a! # toggles @a, so that it ends up being false
42
+ # x.a! # toggles @a, so that it ends up being true
43
+ # x.a! false # sets @a to false
44
+ #
45
+ def bool_attr_accessor(*args)
46
+
47
+ make = {}
48
+ args.each { |a|
49
+ make["#{a}?".to_sym] = %{
50
+ def #{a}?(true_value=true)
51
+ @#{a} ? true_value : @#{a}
52
+ end
53
+ }
54
+ make["#{a}!".to_sym] = %{
55
+ def #{a}!(switch=Exception)
56
+ if switch == Exception
57
+ @#{a} = !@#{a}
58
+ else
59
+ @#{a} = switch ? true : false
60
+ # used to be @#{a} instead of false in Facets version
61
+ self
62
+ end
63
+ end
64
+ }
65
+ }
66
+ module_eval make.values.join("\n"), __FILE__, __LINE__
67
+
68
+ make.keys
69
+ end
70
+
71
+ end
72
+
73
+ class Module
74
+ # This creates two methods for each given variable name. One is used to test
75
+ # the attribute and the other is used to set or toggle it.
76
+ #
77
+ # bool_attr_accessor :a
78
+ #
79
+ # is equivalent to
80
+ #
81
+ # def self.a?
82
+ # @@a ? true : @@a
83
+ # end
84
+ #
85
+ # def self.a!(switch=Exception)
86
+ # if switch == Exception
87
+ # @@a = !@@a
88
+ # else
89
+ # @@a = switch ? true : false
90
+ # self
91
+ # end
92
+ # end
93
+ #
94
+ # Works for both classes and modules.
95
+ #
96
+ def mbool_attr_accessor(*args)
97
+
98
+ make = {}
99
+ args.each { |a|
100
+ # Initialize it first so that we won't have any NameErrors.
101
+ module_eval %{ @@#{a} = nil if !defined?(@@#{a}) }, __FILE__, __LINE__
102
+
103
+ make["#{a}?".to_sym] = %{
104
+ def self.#{a}?(true_value=true)
105
+ @@#{a} ? true_value : @@#{a}
106
+ end
107
+ }
108
+ make["#{a}!".to_sym] = %{
109
+ def self.#{a}!(switch=Exception)
110
+ if switch == Exception
111
+ @@#{a} = !@@#{a}
112
+ else
113
+ @@#{a} = switch ? true : false
114
+ self
115
+ end
116
+ end
117
+ }
118
+ }
119
+ module_eval make.values.join("\n"), __FILE__, __LINE__
120
+
121
+ make.keys
122
+ end
123
+ end
124
+
125
+
126
+
127
+ # _____ _
128
+ # |_ _|__ ___| |_
129
+ # | |/ _ \/ __| __|
130
+ # | | __/\__ \ |_
131
+ # |_|\___||___/\__|
132
+ #
133
+ =begin test
134
+ require 'test/unit'
135
+ require 'rubygems'
136
+ require 'qualitysmith_extensions/object/ignore_access'
137
+ require 'set'
138
+
139
+ # Test that it works for *instances*
140
+ class TestBoolAttr < Test::Unit::TestCase
141
+ def setup
142
+ @x = C.new
143
+ end
144
+
145
+ class C
146
+ bool_attr_accessor :a
147
+ end
148
+
149
+ class C_for_default_is_nil
150
+ bool_attr_accessor :a
151
+ end
152
+
153
+ def test1_default_is_nil
154
+ assert_equal nil, C_for_default_is_nil.new.a?
155
+ end
156
+
157
+ def test2_toggle
158
+ assert_equal nil, @x.a?
159
+ @x.a!
160
+ assert_equal true, @x.a?
161
+ @x.a!
162
+ assert_equal false, @x.a?
163
+ end
164
+
165
+ def test3_setter
166
+ @x.a! true
167
+ @x.a! true
168
+ assert_equal true, @x.a?
169
+
170
+ @x.a! false
171
+ assert_equal false, @x.a?
172
+ end
173
+ def test4_sets_to_boolean_even_if_try_to_set_to_other_type
174
+ @x.a! "whatever"
175
+ assert_equal true, @x.a? # Still returns a boolean even though we tried to set it to a string.
176
+
177
+ @x.a! nil
178
+ assert_equal false, @x.a? # Still returns a boolean even though we tried to set it to nil.
179
+ end
180
+ end
181
+
182
+ # Test that it works for *modules*
183
+ class TestForModules < Test::Unit::TestCase
184
+
185
+ class M_for_default_is_nil
186
+ mbool_attr_accessor :a
187
+ end
188
+ def test1_default_is_nil
189
+ assert_equal nil, M_for_default_is_nil.a?
190
+ end
191
+
192
+ module M
193
+ mbool_attr_accessor :a
194
+ end
195
+ def test2_toggle
196
+ assert_equal nil, M.a?
197
+ M.a!
198
+ assert_equal true, M.a?
199
+ M.a!
200
+ assert_equal false, M.a?
201
+ end
202
+ def test3_setter
203
+ M.a! true
204
+ M.a! true
205
+ assert_equal true, M.a?
206
+
207
+ M.a! false
208
+ assert_equal false, M.a?
209
+ end
210
+ def test4_sets_to_boolean_even_if_try_to_set_to_other_type
211
+ M.a! "whatever"
212
+ assert_equal true, M.a? # Still returns a boolean even though we tried to set it to a string.
213
+
214
+ M.a! nil
215
+ assert_equal false, M.a? # Still returns a boolean even though we tried to set it to nil.
216
+ end
217
+ end
218
+
219
+ # Test that it also works for *classes*
220
+ class TestForClasses < Test::Unit::TestCase
221
+
222
+ class C_for_default_is_nil
223
+ mbool_attr_accessor :a
224
+ end
225
+ def test1_default_is_nil
226
+ assert_equal nil, C_for_default_is_nil.a?
227
+ end
228
+
229
+ class C
230
+ mbool_attr_accessor :a
231
+ end
232
+
233
+ def test2_toggle
234
+ C.access.class_variable_set :@@a, false
235
+ assert_equal false, C.a? # otherwise would have been nil
236
+ C.a!
237
+ assert_equal true, C.a?
238
+ C.a!
239
+ assert_equal false, C.a?
240
+
241
+ assert_equal ["@_ignore_access_functor"], C.instance_variables
242
+ assert_equal ["@@a"], C.class_variables
243
+ end
244
+
245
+ def test3_setter
246
+ C.a! true
247
+ C.a! true
248
+ assert_equal true, C.a?
249
+
250
+ C.a! false
251
+ assert_equal false, C.a?
252
+ end
253
+ def test4_sets_to_boolean_even_if_try_to_set_to_other_type
254
+ C.a! "whatever"
255
+ assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
256
+
257
+ C.a! nil
258
+ assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
259
+ end
260
+ end
261
+
262
+
263
+ # Observation: You can also the normal bool_attr_accessor in conjunction with class << self.
264
+ # The methods generated seem to *behave* in the same way. Both techniques allow you to query the class, C.a?
265
+ # The only difference is in which *variables* are use to store the state:
266
+ # * class << self and the normal bool_attr_accessor:
267
+ # Stores the state in an instance variable for the *class*: @a
268
+ # * mbool_attr_accessor:
269
+ # Stores the state in a *class* variable: @@a
270
+ #
271
+ # Can someone explain to me the difference between class variables and instance variables of a class?
272
+ # It seems silly (confusing even!) to have both of them!
273
+ #
274
+ # My best explanation is that the fact that we can even *have* instance variables of a class does *not* mean it's a good idea
275
+ # to use them. It simply means that Matz made the language with as few arbitrary restrictions as possible. He made it
276
+ # technically *possible* to do a lot of things that it is probably not good practice to do... And one of those things is
277
+ # using instance variables of classes to store state information for that class.
278
+ #
279
+ # What do you think class variables are for? Exactly that! There's a *reason* we have both @a and @@a variables -- to
280
+ # *differentiate* between the two kinds of variables and keep programmers sane. So please don't blur the distinction and
281
+ # use the @a-type variable to do the job that @@a-type variables are for.
282
+ #
283
+ # Or am I missing something here?
284
+ #
285
+ class TestWith_class_self_and_plain_bool_attr_accessor < Test::Unit::TestCase
286
+
287
+ class C_for_default_is_nil
288
+ class << self
289
+ bool_attr_accessor :a
290
+ end
291
+ end
292
+ def test1_default_is_nil
293
+ assert_equal nil, C_for_default_is_nil.a?
294
+ end
295
+
296
+ class C
297
+ class << self
298
+ bool_attr_accessor :a
299
+ end
300
+ end
301
+ # This is where I spotted a class that uses this technique:
302
+ # * Test::Unit::Assertions::AssertionMessage
303
+
304
+ def test_2_toggle
305
+ assert_equal false, C.a? # Why isn't it nil like it is for the instance use case of bool_attr_accessor?
306
+ C.a!
307
+ assert_equal true, C.a?
308
+ C.a!
309
+ assert_equal false, C.a?
310
+
311
+ assert_equal ["@a"], C.instance_variables
312
+ assert_equal [], C.new.instance_variables # @a is an instance variable of the *class* *not* objects of the class -- weird!
313
+ assert_equal [], C.class_variables
314
+ end
315
+
316
+ def test3_setter
317
+ C.a! true
318
+ C.a! true
319
+ assert_equal true, C.a?
320
+
321
+ C.a! false
322
+ assert_equal false, C.a?
323
+ end
324
+ def test4_sets_to_boolean_even_if_try_to_set_to_other_type
325
+ C.a! "whatever"
326
+ assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
327
+
328
+ C.a! nil
329
+ assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
330
+ end
331
+
332
+ end
333
+ =end
334
+
@@ -0,0 +1,9 @@
1
+ #create_setter/constructor :_F, :filename
2
+ #create_setter/constructor :initialize, :filename do
3
+ # extra constructor stuff
4
+ #end
5
+ #
6
+ # def _F(filename)
7
+ # @filename = filename
8
+ # end
9
+ #