instantcache 0.1.0a1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,240 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright © 2011 Ken Coar
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module InstantCache
20
+
21
+ #
22
+ # = InstantCache exceptions
23
+ #
24
+ # Author:: Ken Coar
25
+ # Copyright:: Copyright © 2011 Ken Coar
26
+ # License:: Apache Licence 2.0
27
+ #
28
+ # == Description
29
+ #
30
+ # InstantCache reports problems using Ruby's exception mechanism. Its
31
+ # exceptions are a little different from the usual run-of-the-mill
32
+ # ones, however. Each exception declaration (aside from the
33
+ # superclass) consists solely of a constant named
34
+ # <tt>MessageFormat</tt>, which is a two-element array of strings.
35
+ # The first element is the default text of the message, which is used
36
+ # when the exception is raised without arguments. <i>E.g.</i>,
37
+ #
38
+ # raise InstantCache::Destroyed
39
+ #
40
+ # The second element of the <tt>MessageFormat</tt> array is utilised
41
+ # when a new instance of the exception is created, and the
42
+ # constructor's arguments are used as <tt>sprintf</tt>-style arguments
43
+ # with the <tt>MessageFormat</tt> text.
44
+ #
45
+
46
+ #
47
+ # The superclass for all of the InstantCache exceptions. It
48
+ # provides all the infrastructure needed by the individual specific
49
+ # exceptions.
50
+ #
51
+ class Exception < StandardError
52
+
53
+ #
54
+ # === Description
55
+ #
56
+ # As the superclass, this exception is not intended for direct invocation.
57
+ #
58
+ # === Arguments
59
+ # N/A
60
+ #
61
+ # === Exceptions
62
+ # [<tt>InstantCache::IncompleteException</tt>] This class was
63
+ # subclassed, but the
64
+ # subclass didn't
65
+ # declare the
66
+ # requisite
67
+ # <tt>MessageFormat</tt>
68
+ # constant.
69
+ #
70
+ def initialize(*args)
71
+ @appargs = args.dup
72
+ super(args[0])
73
+ unless (self.class.constants.include?('MessageFormat'))
74
+ raise IncompleteException.new(self.class.name)
75
+ end
76
+ end # End of def initialize
77
+
78
+ #
79
+ # === Description
80
+ # This is an override of the standard exception <tt>message</tt>
81
+ # method, enhanced to deal with our with-or-without-arguments
82
+ # invocation decision mechanism.
83
+ #
84
+ # If the current class has a <b><tt>MessageFormat</tt></b>
85
+ # constant array defined, the first element will be used for the
86
+ # exception message if no arguments were passed to the invocation.
87
+ # Otherwise, the second element of the <tt>MessageFormat</tt>
88
+ # array will be treated as a '%' format string and the invocation
89
+ # arguments as input to the formatting process, the result of
90
+ # which becomes the exception message string.
91
+ #
92
+ # === Arguments
93
+ # <i>None.</i>
94
+ #
95
+ # === Exceptions
96
+ # <i>None.</i>
97
+ #
98
+ def message
99
+ if (self.class.constants.include?('MessageFormat'))
100
+ fmt = self.class::MessageFormat[@appargs.empty? ? 0 : 1]
101
+ return fmt % [ *@appargs ]
102
+ end
103
+ return @message
104
+ end # End of def message
105
+
106
+ #
107
+ # === Description
108
+ # Return the message text of the exception as a string, after
109
+ # applying any appropriate formating.
110
+ #
111
+ # === Arguments
112
+ # <i>None.</i>
113
+ #
114
+ # === Exceptions
115
+ # <i>None.</i>
116
+ #
117
+ def to_s
118
+ return self.message
119
+ end # End of def to_s
120
+
121
+ end # End of class Exception
122
+
123
+ #
124
+ # Some exception was raised with the wrong arguments.
125
+ #
126
+ class IncompleteException < InstantCache::Exception
127
+ #
128
+ # ==== <tt>raise IncompleteException</tt>
129
+ # => InstantCache::IncompleteException: improperly-coded exception raised
130
+ #
131
+ # ==== <tt>raise IncompleteException.new('<i>arg</i>')</tt>
132
+ # => InstantCache::IncompleteException: improperly-coded exception "arg" raised
133
+ #
134
+ MessageFormat = [
135
+ 'improperly-coded exception raised',
136
+ 'improperly-coded exception "%s" raised',
137
+ ]
138
+ end # End of class IncompleteException
139
+
140
+ #
141
+ # Once a variable has been hit by the 'destroy!' method, it
142
+ # becomes inaccessible to the instance.
143
+ #
144
+ class Destroyed < InstantCache::Exception
145
+ #
146
+ # ==== <tt>raise Destroyed</tt>
147
+ # => InstantCache::Destroyed: attempt to access destroyed variable
148
+ #
149
+ # ==== <tt>raise Destroyed.new('<i>arg</i>')</tt>
150
+ # => InstantCache::Destroyed: attempt to access destroyed variable "arg"
151
+ #
152
+ MessageFormat = [
153
+ 'attempt to access destroyed variable',
154
+ 'attempt to access destroyed variable "%s"',
155
+ ]
156
+ end # End of class Destroyed
157
+
158
+ #
159
+ # Our record of the locked status of a cell differs from the information
160
+ # stored in the memcache about it. This Is Not Good.
161
+ #
162
+ class LockInconsistency < InstantCache::Exception
163
+ #
164
+ # ==== <tt>raise LockInconsistency</tt>
165
+ # => InstantCache::LockInconsistency: interlock cell inconsistency
166
+ #
167
+ # ==== <tt>raise LockInconsistency.new('<i>name</i>', '<i>true</i>', '<i>false</i>')</tt>
168
+ # => InstantCache::LockInconsistency: interlock cell inconsistency
169
+ # cell='name', expected='true', actual='false'
170
+ #
171
+ MessageFormat = [
172
+ 'interlock cell inconsistency',
173
+ "interlock cell inconsistency\n" +
174
+ "\tcell='%s', expected='%s', actual='%s'",
175
+ ]
176
+ end # End of class LockInconsistency
177
+
178
+ #
179
+ # User-supplied names are only permitted for shared variables;
180
+ # otherwise private ones may get inadvertently shared and bollixed.
181
+ #
182
+ class SharedOnly < InstantCache::Exception
183
+ #
184
+ # ==== <tt>raise SharedOnly</tt>
185
+ # => InstantCache::SharedOnly: custom names are only permitted for shared variables
186
+ #
187
+ # ==== <tt>raise SharedOnly.new('<i>name</i>')</tt>
188
+ # => InstantCache::SharedOnly: custom names are only permitted for shared variables; 'name' is labelled as private
189
+ #
190
+ MessageFormat = [
191
+ 'custom names are only permitted for shared variables',
192
+ ('custom names are only permitted for shared variables; ' +
193
+ "'%s' is labelled as private"),
194
+ ]
195
+ end # End of class SharedOnly
196
+
197
+ #
198
+ # Counter variables are only permitted to be frobbed with integers.
199
+ # We gritch if anything else is attempted.
200
+ #
201
+ class CounterIntegerOnly < InstantCache::Exception
202
+ #
203
+ # ==== <tt>raise CounterIntegerOnly</tt>
204
+ # => InstantCache::CounterIntegerOnly: variables declared as counters are integer-only
205
+ #
206
+ # ==== <tt>raise CounterIntegerOnly.new('<i>name</i>')</tt>
207
+ # => InstantCache::CounterIntegerOnly: variables declared as counters are integer-only: name
208
+ #
209
+ MessageFormat = [
210
+ 'variables declared as counters are integer-only',
211
+ 'variables declared as counters are integer-only: %s',
212
+ ]
213
+ end # End of class CounterIntegerOnly
214
+
215
+ #
216
+ # Because of the annotation of returned values with callback singleton
217
+ # methods, it's possible for multiple user variables to hold references
218
+ # to a cell. <i>E.g.</i>, one might remember the cell as a hash and
219
+ # modify an element, even though the cell has actually be explicitly
220
+ # set to something else. This exception is raised if there's a mismatch
221
+ # when an annotation tries to update the cell.
222
+ #
223
+ # TODO: This is not working properly yet.
224
+ #
225
+ class IncompatibleType < InstantCache::Exception
226
+ #
227
+ # ==== <tt>raise IncompatibleType</tt>
228
+ # => InstantCache::IncompatibleType: variable class incompatible with cached value
229
+ #
230
+ # ==== <tt>raise IncompatibleType.new('<i>Hash</i>', '<i>Array</i>', '<i>name</i>')</tt>
231
+ # => InstantCache::IncompatibleType: variable class "Hash" incompatible with class "Array" of cached variable "name"',
232
+ #
233
+ MessageFormat = [
234
+ 'variable class incompatible with cached value',
235
+ 'variable class "%s" incompatible with class "%s" ' +
236
+ 'of cached variable "%s"',
237
+ ]
238
+ end # End of class IncompatibleType
239
+
240
+ end # End of module InstantCache