qualitysmith_extensions 0.0.24 → 0.0.29

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,309 +0,0 @@
1
- #--
2
- # Author:: Tyler Rick
3
- # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
- # License:: Ruby License
5
- # Submit to Facets?:: Yes!
6
- # Developer notes::
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
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?
12
- #++
13
-
14
- require 'rubygems'
15
- require 'qualitysmith_extensions/module/attribute_accessors'
16
- require 'qualitysmith_extensions/module/mattr_tester'
17
- require 'qualitysmith_extensions/module/attr_tester'
18
- require 'qualitysmith_extensions/symbol/match'
19
-
20
-
21
- class Module
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)
60
- raise ArgumentError.new("Expected an instance variable name but got #{guard_variable}") if guard_variable !~ /^@([\w_]+)$/
61
- guard_variable.to_s =~ /^@([\w_]+)$/ # Why didn't the regexp above set $1 ??
62
- class_eval do
63
- attr_tester $1.to_sym
64
- end
65
- module_eval <<-End, __FILE__, __LINE__+1
66
- def #{guard_method_name}(new_value = nil, &block)
67
- old_guard_state, #{guard_variable} = #{guard_variable}, true
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
83
- end
84
- End
85
- end
86
-
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)
94
- raise ArgumentError.new("Expected a class variable name but got #{guard_variable}") if guard_variable !~ /^@@[\w_]+$/
95
- guard_variable.to_s =~ /^@@([\w_]+)$/
96
- class_eval do
97
- mattr_tester $1.to_sym
98
- end
99
- module_eval <<-End, __FILE__, __LINE__+1
100
- class << self
101
- def #{guard_method_name}(new_value = nil, &block)
102
- old_guard_state, #{guard_variable} = #{guard_variable}, true
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
120
- end
121
- end
122
- End
123
- end
124
- end
125
-
126
-
127
- # _____ _
128
- # |_ _|__ ___| |_
129
- # | |/ _ \/ __| __|
130
- # | | __/\__ \ |_
131
- # |_|\___||___/\__|
132
- #
133
- =begin test
134
- require 'test/unit'
135
-
136
- class GuardMethodTest_Simple < Test::Unit::TestCase
137
- class A
138
- guard_method :guard_the_fruit!, :@guarding_the_fruit
139
- end
140
- def test_guard_method
141
- a = A.new
142
- assert_equal nil, a.guarding_the_fruit?
143
- a.guard_the_fruit! do
144
- # Call it recursively!
145
- a.guard_the_fruit! do
146
- assert_equal true, a.guarding_the_fruit?
147
- end
148
- assert_equal true, a.guarding_the_fruit? # This is the reason why we have to save the 'old_guard_state'. So that we don't stupidly set it back to false if we still haven't exited from the outermost call to the guard black.
149
- end
150
- assert_equal nil, a.guarding_the_fruit?
151
- end
152
- def test_guard_method_error
153
- assert_raise(ArgumentError) do
154
- self.class.class_eval do
155
- guard_method :guard_the_fruit!, :@@guarding_the_fruit
156
- end
157
- end
158
- end
159
- def test_return_value
160
- assert_equal 'special return value', A.new.guard_the_fruit! { 'special return value' }
161
- end
162
- end
163
-
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
228
- class B
229
- mguard_method :guard_the_fruit!, :@@guarding_the_fruit
230
- end
231
- def test_mguard_method
232
- assert_equal nil, B.guarding_the_fruit?
233
- B.guard_the_fruit! do
234
- # Call it recursively!
235
- B.guard_the_fruit! do
236
- assert_equal true, B.guarding_the_fruit?
237
- end
238
- assert_equal true, B.guarding_the_fruit? # This is the reason why we have to save the 'old_guard_state'. So that we don't stupidly set it back to false if we still haven't exited from the outermost call to the guard black.
239
- end
240
- assert_equal nil, B.guarding_the_fruit?
241
- end
242
- def test_mguard_method_error
243
- assert_raise(ArgumentError) do
244
- self.class.class_eval do
245
- mguard_method :guard_the_fruit!, :@guarding_the_fruit
246
- end
247
- end
248
- end
249
- def test_return_value
250
- assert_equal 'special return value', B.guard_the_fruit! { 'special return value' }
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?
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
305
- end
306
- # End duplication
307
- #---------------------------------------------------------------------------------------------------------------------------------
308
- =end
309
-
@@ -1,10 +0,0 @@
1
-
2
- # mattr_accessor :already_included
3
- # def self.already_included
4
- # @@already_included ||= false
5
- # end
6
- #
7
- # def self.included(base_module)
8
- # return if @@already_included
9
- # @@already_included = true
10
- #
@@ -1,235 +0,0 @@
1
- #--
2
- # Author:: 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 would rename this one to bool_attr_accessor, which calls both bool_attr_reader and bool_attr_writer, but also lets you just create a reader or writer if you so desire.
10
- #++
11
-
12
- class Module
13
- # This creates two methods for each given variable name. One is used to test
14
- # the attribute and the other is used to set or toggle it.
15
- #
16
- # bool_attr_accessor :a
17
- #
18
- # is equivalent to
19
- #
20
- # def self.a?
21
- # @@a ? true : @@a
22
- # end
23
- #
24
- # def self.a!(switch=Exception)
25
- # if switch == Exception
26
- # @@a = !@@a
27
- # else
28
- # @@a = switch ? true : false
29
- # self
30
- # end
31
- # end
32
- #
33
- # Works for both classes and modules.
34
- #
35
- def mbool_attr_accessor(*args)
36
-
37
- make = {}
38
- args.each { |a|
39
- # Initialize it first so that we won't have any NameErrors.
40
- module_eval %{ @@#{a} = nil if !defined?(@@#{a}) }, __FILE__, __LINE__
41
-
42
- make["#{a}?".to_sym] = %{
43
- def self.#{a}?(true_value=true)
44
- @@#{a} ? true_value : @@#{a}
45
- end
46
- }
47
- make["#{a}!".to_sym] = %{
48
- def self.#{a}!(switch=Exception)
49
- if switch == Exception
50
- @@#{a} = !@@#{a}
51
- else
52
- @@#{a} = switch ? true : false
53
- self
54
- end
55
- end
56
- }
57
- }
58
- module_eval make.values.join("\n"), __FILE__, __LINE__
59
-
60
- make.keys
61
- end
62
- end
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
- # _____ _
71
- # |_ _|__ ___| |_
72
- # | |/ _ \/ __| __|
73
- # | | __/\__ \ |_
74
- # |_|\___||___/\__|
75
- #
76
- =begin test
77
- require 'test/unit'
78
- require 'rubygems'
79
- require 'qualitysmith_extensions/object/ignore_access'
80
- require 'set'
81
-
82
- require 'qualitysmith_extensions/module/bool_attr_accessor' # Simply to show a comparison of mbool_attr_accessor and using class<<self and bool_attr_accessor
83
-
84
- # Test that it works for *modules*
85
- class TestForModules < Test::Unit::TestCase
86
-
87
- class M_for_default_is_nil
88
- mbool_attr_accessor :a
89
- end
90
- def test1_default_is_nil
91
- assert_equal nil, M_for_default_is_nil.a?
92
- end
93
-
94
- module M
95
- mbool_attr_accessor :a
96
- end
97
- def test2_toggle
98
- assert_equal nil, M.a?
99
- M.a!
100
- assert_equal true, M.a?
101
- M.a!
102
- assert_equal false, M.a?
103
- end
104
- def test3_setter
105
- M.a! true
106
- M.a! true
107
- assert_equal true, M.a?
108
-
109
- M.a! false
110
- assert_equal false, M.a?
111
- end
112
- def test4_sets_to_boolean_even_if_try_to_set_to_other_type
113
- M.a! "whatever"
114
- assert_equal true, M.a? # Still returns a boolean even though we tried to set it to a string.
115
-
116
- M.a! nil
117
- assert_equal false, M.a? # Still returns a boolean even though we tried to set it to nil.
118
- end
119
- end
120
-
121
- # Test that it also works for *classes*
122
- class TestForClasses < Test::Unit::TestCase
123
-
124
- class C_for_default_is_nil
125
- mbool_attr_accessor :a
126
- end
127
- def test1_default_is_nil
128
- assert_equal nil, C_for_default_is_nil.a?
129
- end
130
-
131
- class C
132
- mbool_attr_accessor :a
133
- end
134
-
135
- def test2_toggle
136
- C.access.class_variable_set :@@a, false
137
- assert_equal false, C.a? # otherwise would have been nil
138
- C.a!
139
- assert_equal true, C.a?
140
- C.a!
141
- assert_equal false, C.a?
142
-
143
- assert_equal ["@_ignore_access_functor"], C.instance_variables
144
- assert_equal ["@@a"], C.class_variables
145
- end
146
-
147
- def test3_setter
148
- C.a! true
149
- C.a! true
150
- assert_equal true, C.a?
151
-
152
- C.a! false
153
- assert_equal false, C.a?
154
- end
155
- def test4_sets_to_boolean_even_if_try_to_set_to_other_type
156
- C.a! "whatever"
157
- assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
158
-
159
- C.a! nil
160
- assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
161
- end
162
- end
163
-
164
-
165
- # Observation: You can also the normal bool_attr_accessor in conjunction with class << self.
166
- # The methods generated seem to *behave* in the same way. Both techniques allow you to query the class, C.a?
167
- # The only difference is in which *variables* are use to store the state:
168
- # * class << self and the normal bool_attr_accessor:
169
- # Stores the state in an instance variable for the *class*: @a
170
- # * mbool_attr_accessor:
171
- # Stores the state in a *class* variable: @@a
172
- #
173
- # Can someone explain to me the difference between class variables and instance variables of a class?
174
- # It seems silly (confusing even!) to have both of them!
175
- #
176
- # 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
177
- # to use them. It simply means that Matz made the language with as few arbitrary restrictions as possible. He made it
178
- # technically *possible* to do a lot of things that it is probably not good practice to do... And one of those things is
179
- # using instance variables of classes to store state information for that class.
180
- #
181
- # What do you think class variables are for? Exactly that! There's a *reason* we have both @a and @@a variables -- to
182
- # *differentiate* between the two kinds of variables and keep programmers sane. So please don't blur the distinction and
183
- # use the @a-type variable to do the job that @@a-type variables are for.
184
- #
185
- # Or am I missing something here?
186
- #
187
- class TestWith_class_self_and_plain_bool_attr_accessor < Test::Unit::TestCase
188
-
189
- class C_for_default_is_nil
190
- mbool_attr_accessor :a
191
- end
192
- def test1_default_is_nil
193
- assert_equal nil, C_for_default_is_nil.a?
194
- end
195
-
196
- class C
197
- class << self
198
- bool_attr_accessor :a
199
- end
200
- end
201
- # This is where I spotted a class that uses this technique:
202
- # * Test::Unit::Assertions::AssertionMessage
203
-
204
- def test_2_toggle
205
- assert_equal nil, C.a?
206
- C.a!
207
- assert_equal true, C.a?
208
- C.a!
209
- assert_equal false, C.a?
210
-
211
- assert_equal ["@a"], C.instance_variables
212
- assert_equal [], C.new.instance_variables # @a is an instance variable of the *class* *not* objects of the class -- weird!
213
- assert_equal [], C.class_variables
214
- end
215
-
216
- def test3_setter
217
- C.a! true
218
- C.a! true
219
- assert_equal true, C.a?
220
-
221
- C.a! false
222
- assert_equal false, C.a?
223
- end
224
- def test4_sets_to_boolean_even_if_try_to_set_to_other_type
225
- C.a! "whatever"
226
- assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
227
-
228
- C.a! nil
229
- assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
230
- end
231
-
232
- end
233
-
234
- =end
235
-