y_support 2.1.18 → 2.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/y_support/all.rb +2 -32
- data/lib/y_support/core_ext/array.rb +2 -2
- data/lib/y_support/core_ext/class.rb +2 -2
- data/lib/y_support/core_ext/enumerable.rb +2 -2
- data/lib/y_support/core_ext/hash/misc.rb +23 -10
- data/lib/y_support/core_ext/hash.rb +2 -2
- data/lib/y_support/core_ext/module/misc.rb +9 -0
- data/lib/y_support/core_ext/module.rb +2 -2
- data/lib/y_support/core_ext/numeric.rb +2 -2
- data/lib/y_support/core_ext/object/inspection.rb +8 -2
- data/lib/y_support/core_ext/object.rb +3 -3
- data/lib/y_support/core_ext/string/misc.rb +9 -12
- data/lib/y_support/core_ext/string.rb +2 -2
- data/lib/y_support/core_ext/symbol.rb +2 -2
- data/lib/y_support/core_ext.rb +1 -1
- data/lib/y_support/flex_coerce/class_methods.rb +49 -0
- data/lib/y_support/flex_coerce/flex_proxy.rb +121 -0
- data/lib/y_support/flex_coerce/module_methods.rb +37 -0
- data/lib/y_support/flex_coerce.rb +24 -0
- data/lib/y_support/kde.rb +1 -1
- data/lib/y_support/literate.rb +253 -0
- data/lib/y_support/local_object.rb +1 -1
- data/lib/y_support/name_magic/array_methods.rb +48 -0
- data/lib/y_support/name_magic/class_methods.rb +205 -161
- data/lib/y_support/name_magic/hash_methods.rb +33 -0
- data/lib/y_support/name_magic/namespace.rb +449 -0
- data/lib/y_support/name_magic.rb +358 -100
- data/lib/y_support/null_object.rb +1 -1
- data/lib/y_support/respond_to.rb +1 -1
- data/lib/y_support/stdlib_ext/matrix/misc.rb +2 -2
- data/lib/y_support/stdlib_ext/matrix.rb +2 -2
- data/lib/y_support/stdlib_ext.rb +1 -1
- data/lib/y_support/typing/array.rb +1 -1
- data/lib/y_support/typing/enumerable.rb +1 -1
- data/lib/y_support/typing/hash.rb +1 -1
- data/lib/y_support/typing/module.rb +1 -1
- data/lib/y_support/typing/object/typing.rb +17 -15
- data/lib/y_support/typing/object.rb +1 -1
- data/lib/y_support/typing.rb +14 -10
- data/lib/y_support/unicode.rb +1 -1
- data/lib/y_support/version.rb +1 -1
- data/lib/y_support/x.rb +2 -1
- data/test/flex_coerce_test.rb +134 -0
- data/test/literate_test.rb +231 -0
- data/test/misc_test.rb +49 -27
- data/test/name_magic_test.rb +907 -60
- data/test/typing_test.rb +7 -7
- metadata +14 -13
- data/lib/y_support/abstract_algebra.rb +0 -234
- data/lib/y_support/name_magic/array.rb +0 -38
- data/lib/y_support/name_magic/hash.rb +0 -31
- data/lib/y_support/name_magic/namespace_methods.rb +0 -260
- data/lib/y_support/try.rb +0 -133
- data/test/abstract_algebra_test.rb +0 -138
- data/test/performance_test_example.rb +0 -23
- data/test/try_test.rb +0 -102
@@ -0,0 +1,449 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Module methods for the modules serving as +NameMagic+
|
4
|
+
# namespaces. What is a +NameMagic+ namespace? For a class that
|
5
|
+
# includes +NameMagic+, namespace is the "civil registry" of all
|
6
|
+
# instances, both named and nameless. For this purpose, namespace
|
7
|
+
# has variable +@instances+. The registry of instances is a hash of
|
8
|
+
# pairs <tt>{ instance => name }</tt>. Nameless instances have
|
9
|
+
# _nil_ value instead of name in the registry. In general Ruby,
|
10
|
+
# namespace would mean that the module holds the instances in
|
11
|
+
# constants looking like <tt>Namespace::Name</tt>. In Ruby core, we
|
12
|
+
# can see such behavior with Struct class, which has native
|
13
|
+
# constant magic and stores its instances in constants using Struct
|
14
|
+
# as a namespace. NameMagic used to perform this constant
|
15
|
+
# assignment in the namespace prior to YSupport version ~2.0. This
|
16
|
+
# is one of the reasons why names of instances must start with a
|
17
|
+
# capital letter and be usable as constant names. Since YSupport
|
18
|
+
# version 2.0+, NameMagic does no constant assignment on its own --
|
19
|
+
# all constant assignments are left to the user. In this way,
|
20
|
+
# NameMagic now sees constant assignment purely as a way to learn
|
21
|
+
# instance names intended by the user.
|
22
|
+
#
|
23
|
+
# The instance registry is accessible via +#instances+
|
24
|
+
# method. Individual instances can be queried for by +#instance+
|
25
|
+
# method, eg. by their names. Until Matz provides the possibility
|
26
|
+
# of constant magic in every class, which I requested some time
|
27
|
+
# ago, the registry of instances will remain the essential part,
|
28
|
+
# without which +NameMagic wouldn't work.
|
29
|
+
#
|
30
|
+
# === Life cycle of instances of +NameMagic+ user classes
|
31
|
+
#
|
32
|
+
# Let us consider for example Human class that uses NameMagic.
|
33
|
+
#
|
34
|
+
# class Human
|
35
|
+
# require 'y_support/name_magic'
|
36
|
+
# include NameMagic
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# Life cycle of Human in instances of begins, unsurprisingly, by
|
40
|
+
# instantiation. All instances are created nameless:
|
41
|
+
#
|
42
|
+
# newborn = Human.new
|
43
|
+
# newborn.name #=> nil
|
44
|
+
#
|
45
|
+
# User has several ways of naming the instances. Typical for
|
46
|
+
# +NameMagic+ is naming by constant assignment:
|
47
|
+
#
|
48
|
+
# Fred = newborn
|
49
|
+
# newborn.name #=> :Fred
|
50
|
+
#
|
51
|
+
# +NameMagic makes it possible to supply :name parameter directly
|
52
|
+
# to the #new method. Such instances are named immediately:
|
53
|
+
#
|
54
|
+
# newborn = Human.new name: "Joe"
|
55
|
+
# newborn.name #=> :Joe
|
56
|
+
#
|
57
|
+
# Another way is to name the instances using #name= method.
|
58
|
+
#
|
59
|
+
# newborn = Human.new
|
60
|
+
# newborn.name #=> nil
|
61
|
+
# newborn.name = "Mike"
|
62
|
+
# newborn.name #=> Mike
|
63
|
+
#
|
64
|
+
# Just for the record, we have created three instances:
|
65
|
+
#
|
66
|
+
# Human.instances #=> [Fred, Joe, Mike]
|
67
|
+
#
|
68
|
+
# In other words, at some point in their life, instances may or may
|
69
|
+
# not undergo baptism, which involves a complicated procedure of
|
70
|
+
# searching all existing Ruby modules for constants to which
|
71
|
+
# nameless instances of the class in question are
|
72
|
+
# assigned. Baptized instances then know their names, and can be
|
73
|
+
# accessed by their names through the instance registry:
|
74
|
+
#
|
75
|
+
# Human.instance( "Mike" ) #=> Mike
|
76
|
+
#
|
77
|
+
# Namespace gives the user 2 hook methods, #instantiation_exec and
|
78
|
+
# #exec_when_naming. The first one is executed upon instantiation
|
79
|
+
# and passed one argument, the new instance. The second one is
|
80
|
+
# executed when the namespace baptizes a new instance, and passed
|
81
|
+
# three arguments: suggested name, instance, and previous name if
|
82
|
+
# any. (Renaming instances may require special care.) Consequantly,
|
83
|
+
# you should define unary block with #instantiation_exec and
|
84
|
+
# ternary one with #exec_when_naming. Example:
|
85
|
+
#
|
86
|
+
# Human.instantiation_exec do |instance|
|
87
|
+
# puts "Instance with object id #{instance.object_id} created!"
|
88
|
+
# end
|
89
|
+
# newborn = Human.new #=> Instance with object id 75756140 created!
|
90
|
+
#
|
91
|
+
# The naming hook can also be used to censor and modify the
|
92
|
+
# intended name. Consider the following censorship:
|
93
|
+
#
|
94
|
+
# Human.exec_when_naming do |name, instance, old_name|
|
95
|
+
# fail NameError, "#{name.capitalize} is not a saint in the " +
|
96
|
+
# "Church of Emacs!" unless name.end_with? "gnucius"
|
97
|
+
# "St_IGNUcius"
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# Now we can no longer use ordinary names, we have to use names of
|
101
|
+
# saints in the Church of Emacs!
|
102
|
+
#
|
103
|
+
# newborn.name = "Dave"
|
104
|
+
# #=> NameError: Dave is not a saint in the Church of Emacs!
|
105
|
+
#
|
106
|
+
# Name Ignucius is OK, but the censor corrects it to St_IGNUcius:
|
107
|
+
#
|
108
|
+
# newborn.name = "Ignucius" #=> St_IGNUcius
|
109
|
+
#
|
110
|
+
# Life cycle of an instance ends when it is deleted from the
|
111
|
+
# instance registry and garbage-collected (unless something else
|
112
|
+
# holds a reference to it). Example:
|
113
|
+
#
|
114
|
+
# Human.instances #=> [Fred, Joe, Mike, St_IGNUcius]
|
115
|
+
# Human.forget "St_IGNUcius"
|
116
|
+
# Human.instances #=> [Fred, Joe, Mike]
|
117
|
+
#
|
118
|
+
# St. IGNUcius has just been deleted from the registry.
|
119
|
+
#
|
120
|
+
# Human.forget_all_instances
|
121
|
+
# Human.instances #=> []
|
122
|
+
#
|
123
|
+
# All Human instances have now been deleted from the registry, but
|
124
|
+
# only Joe and Mike are garbage-collected, because Fred is still
|
125
|
+
# assigned to a constant. Fred still exists, but he and his name
|
126
|
+
# has been deleted from the instance registry.
|
127
|
+
#
|
128
|
+
# Fred #=> #<Human:0x89449b0>
|
129
|
+
#
|
130
|
+
# We could even re-register Fred by recreating his entry, although
|
131
|
+
# this is far from the way +NameMagic+ works in everyday life.
|
132
|
+
#
|
133
|
+
# Human.__instances__.merge! Fred => :Fred
|
134
|
+
# Human.instances #=> [Fred]
|
135
|
+
#
|
136
|
+
# === Avidity of the instances
|
137
|
+
#
|
138
|
+
# After the offered name is checked and modified by the name set
|
139
|
+
# hook closure, there is one more remaining problem to worry about:
|
140
|
+
# Whether the name is already used by another instance in the same
|
141
|
+
# namespace. If the name is taken, the ensuing action depends on
|
142
|
+
# whether the instance being named is _avid_. Avid instances are
|
143
|
+
# so eager to get a name, that they will steal the offered name for
|
144
|
+
# themselves even if other instances already use the name, making
|
145
|
+
# the conflicting instance nameless in the process. In +NameMagic+,
|
146
|
+
# it turns out to be convenient to make the new instances avid by
|
147
|
+
# default, unless the name was explicitly supplied to the
|
148
|
+
# constructor by +:name+ argument, or avidity suppressed by setting
|
149
|
+
# +:name_avid option to _false_.
|
150
|
+
#
|
151
|
+
# Techincally, avid instances are registered as an array kept by
|
152
|
+
# the namespace under the variable +@avid_instances+.
|
153
|
+
#
|
154
|
+
# === Forgetting instances
|
155
|
+
#
|
156
|
+
# As mentioned earlier, namespace can de-register, or forget
|
157
|
+
# instances. For this purpose, see methods +#forget+, +#__forget__,
|
158
|
+
# +#forget_nameless_instances+, +#forget_all_instances+.
|
159
|
+
#
|
160
|
+
# === Ersatz constant magic
|
161
|
+
#
|
162
|
+
# To imitate built-in constant magic of some Ruby classes,
|
163
|
+
# +NamespaceMethods+ provides ersatz method +#const_magic+, that
|
164
|
+
# searches all the modules in the object space for the pertinent
|
165
|
+
# instances newly assigned to constants. Method +#const_magic+ is
|
166
|
+
# called automatically before executing almost every public method
|
167
|
+
# of +NameMagic+, thus keeping the "civil registry"
|
168
|
+
# up-to-date. While not exactly computationally efficient, it tends
|
169
|
+
# to make the user code more readable and pays off in most
|
170
|
+
# usecases. For efficiency, we are looking forward to the
|
171
|
+
# +#const_assigned+ hook promised by Ruby core team...
|
172
|
+
#
|
173
|
+
# The namespace method versions that _do_ _not_ perform ersatz
|
174
|
+
# constant magic are generally denoted by underlines: Eg. methods
|
175
|
+
# +#__instances__+ and +#__forget__+ do not perform constant magic,
|
176
|
+
# while +#instances+ and +#forget+ do.
|
177
|
+
#
|
178
|
+
module NameMagic::Namespace
|
179
|
+
# Orders the namespace to disallow unnaming instances. As a
|
180
|
+
# consequence, the instances' names will now be permanent.
|
181
|
+
#
|
182
|
+
def permanent_names!
|
183
|
+
@permanent_names = true
|
184
|
+
end
|
185
|
+
|
186
|
+
# Inquirer whether unnaming instances has been disallowed in
|
187
|
+
# the namespace.
|
188
|
+
#
|
189
|
+
def permanent_names?
|
190
|
+
@permanent_names
|
191
|
+
end
|
192
|
+
|
193
|
+
# Presents the instances registered in this namespace.
|
194
|
+
#
|
195
|
+
def instances *args
|
196
|
+
const_magic
|
197
|
+
__instances__.keys
|
198
|
+
end
|
199
|
+
|
200
|
+
# Presents namespace-owned +@instances+ hash. The hash consists
|
201
|
+
# of pairs <code>{ instance => instance_name }</code>. Unnamed
|
202
|
+
# instances have +nil+ value instead of their name. This method
|
203
|
+
# does not trigger +#const_magic+.
|
204
|
+
#
|
205
|
+
def __instances__
|
206
|
+
@instances ||= {}
|
207
|
+
end
|
208
|
+
|
209
|
+
# Avid instances registered in this namespace. ("Avid" means that
|
210
|
+
# the instance will steal (overwrite) a name from another
|
211
|
+
# instance, should there be a conflict. The method does not
|
212
|
+
# trigger +#const_magic+.
|
213
|
+
#
|
214
|
+
def __avid_instances__
|
215
|
+
@avid_instances ||= []
|
216
|
+
end
|
217
|
+
|
218
|
+
# Returns the instance identified by the argument.
|
219
|
+
#
|
220
|
+
def instance arg
|
221
|
+
# In @instances hash, nil value denotes nameless instances!
|
222
|
+
fail TypeError,
|
223
|
+
"Nil is not an instance identifier!" if arg.nil?
|
224
|
+
# Get the list of all instances.
|
225
|
+
ii = instances
|
226
|
+
# If arg belongs to the list, just return it back.
|
227
|
+
return arg if ii.include? arg
|
228
|
+
# Assume that arg is an instance name.
|
229
|
+
name = arg.to_sym
|
230
|
+
registry = __instances__
|
231
|
+
ii.find { |i| registry[ i ] == name } or
|
232
|
+
fail NameError, "No instance #{arg} in #{self}!"
|
233
|
+
end
|
234
|
+
|
235
|
+
# Searches all the modules in the the object space for constants
|
236
|
+
# referring to receiver class objects, and names the found
|
237
|
+
# instances accordingly. Internally, it works by invoking
|
238
|
+
# private procedure +#search_all_modules. The return value is
|
239
|
+
# the remaining number of nameless instances.
|
240
|
+
#
|
241
|
+
def const_magic
|
242
|
+
return 0 if nameless_instances.size == 0
|
243
|
+
search_all_modules
|
244
|
+
return nameless_instances.size
|
245
|
+
end
|
246
|
+
|
247
|
+
# Returns those instances, whose name is nil. This method does
|
248
|
+
# not trigger #const_magic.
|
249
|
+
#
|
250
|
+
def nameless_instances *args
|
251
|
+
__instances__.select { |key, val| val.nil? }.keys
|
252
|
+
end
|
253
|
+
|
254
|
+
# Removes the specified instance from the registry. Note that
|
255
|
+
# this is different from "unnaming" an instance by setting
|
256
|
+
# <code>inst.name = nil</code>, which makes the instance
|
257
|
+
# anonymous, but still registered.
|
258
|
+
#
|
259
|
+
def forget instance, *args
|
260
|
+
instance = begin
|
261
|
+
instance instance
|
262
|
+
rescue ArgumentError
|
263
|
+
return nil # nothing to forget
|
264
|
+
end
|
265
|
+
ɴ = instance.nil? ? nil : instance.name
|
266
|
+
# namespace.send :remove_const, ɴ if ɴ
|
267
|
+
__instances__.delete( instance )
|
268
|
+
__avid_instances__.delete( instance )
|
269
|
+
return instance
|
270
|
+
end
|
271
|
+
|
272
|
+
# Removes the specified instance from the registry, without
|
273
|
+
# performing #const_magic first. The argument should be a
|
274
|
+
# registered instance. Returns instance name for forgotten named
|
275
|
+
# instances, _nil_ for forgotten nameless instances, and _false_
|
276
|
+
# if the argument was not a registered instance.
|
277
|
+
#
|
278
|
+
def __forget__ instance
|
279
|
+
return false unless __instances__.keys.include? instance
|
280
|
+
# namespace.send :remove_const, instance.name if instance.name
|
281
|
+
__avid_instances__.delete( instance )
|
282
|
+
__instances__.delete instance
|
283
|
+
end
|
284
|
+
|
285
|
+
# Removes all anonymous instances from the registry.
|
286
|
+
#
|
287
|
+
def forget_nameless_instances
|
288
|
+
const_magic # #nameless_instances doesn't trigger it
|
289
|
+
nameless_instances.each { |instance|
|
290
|
+
__instances__.delete( instance )
|
291
|
+
__avid_instances__.delete( instance )
|
292
|
+
}
|
293
|
+
end
|
294
|
+
|
295
|
+
# Clears references to all the instances.
|
296
|
+
#
|
297
|
+
def forget_all_instances
|
298
|
+
instances.map { |instance| __forget__ instance }
|
299
|
+
# constants( false ).each { |sym|
|
300
|
+
# namespace.send :remove_const, sym if
|
301
|
+
# const_get( sym ).is_a? self }
|
302
|
+
end
|
303
|
+
|
304
|
+
# Registers a block to execute when a new instance of the
|
305
|
+
# +NameMagic+ user class is created. (In other words, this method
|
306
|
+
# provides user class'es instantiation hook.) Expects a unary
|
307
|
+
# block, whose argument is the new instance. Return value of the
|
308
|
+
# block is unimportant. The block will be executed in the context
|
309
|
+
# of the user class. If no block is given, the method returns the
|
310
|
+
# previously defined block, if any, or a default block that does
|
311
|
+
# nothing.
|
312
|
+
#
|
313
|
+
def instantiation_exec &block
|
314
|
+
@instantiation_exec = block if block
|
315
|
+
@instantiation_exec ||= -> instance { }
|
316
|
+
end
|
317
|
+
# Note: This alias must stay while the dependencies need it.
|
318
|
+
alias new_instance_hook instantiation_exec
|
319
|
+
|
320
|
+
# Registers a block to execute just prior to naming of an
|
321
|
+
# instance. (In other words, this method provides user class'es
|
322
|
+
# naming hook.) The block will be executed in the context of the
|
323
|
+
# user class and will be supplied three ordered arguments:
|
324
|
+
# suggested name, instance, and previous name. The block should
|
325
|
+
# thus be written as ternary, expecting these three arguments.
|
326
|
+
# The block can be used to validate / censor the suggested name
|
327
|
+
# and for this reason, it should return the censored name that
|
328
|
+
# will actually be requested for the instance. (Of course, just
|
329
|
+
# like there is no duty to use this hook, if you do use it, there
|
330
|
+
# is likewise no duty to censor the suggested name in it. You can
|
331
|
+
# just return the suggested name unchanged from the block.) The
|
332
|
+
# point is that the return value of the block will actually be
|
333
|
+
# used to name the instance. If no block is given, the method
|
334
|
+
# returns the previously defined block, if any, or a default
|
335
|
+
# block that does nothing and returns the suggested name without
|
336
|
+
# any changes.
|
337
|
+
#
|
338
|
+
def exec_when_naming &block
|
339
|
+
@exec_when_naming = block if block
|
340
|
+
@exec_when_naming ||=
|
341
|
+
-> name, instance, previous_name=nil { name }
|
342
|
+
end
|
343
|
+
# Note: This alias must stay while the dependencies need it.
|
344
|
+
alias name_set_hook exec_when_naming
|
345
|
+
|
346
|
+
# Registers a block to execute just prior to unnaming of an
|
347
|
+
# instance. (In other words, this method provides user class'es
|
348
|
+
# unnaming hook.) The block will be executed in the context of
|
349
|
+
# the user class and will be supplied two ordered arguments:
|
350
|
+
# instance and its previous name. The block can thus be written
|
351
|
+
# as up to binary. Return value of the block is unimportant. If
|
352
|
+
# no block is given, the method returns the block defined
|
353
|
+
# earlier, if any, or a default block that does nothing.
|
354
|
+
#
|
355
|
+
def exec_when_unnaming &block
|
356
|
+
@exec_when_unnaming = block if block
|
357
|
+
@exec_when_unnaming ||= -> instance, previous_name=nil { }
|
358
|
+
end
|
359
|
+
|
360
|
+
# Checks whether a name is acceptable as a constant name.
|
361
|
+
#
|
362
|
+
def validate_name name
|
363
|
+
# Note that the #try method (provided by 'y_support/literate')
|
364
|
+
# allows us to call the methods of name without mentioning
|
365
|
+
# it explicitly as the receiver, and it also allows us to
|
366
|
+
# raise errors without explicitly constructing the error
|
367
|
+
# messages. Thus, chars.first actually means name.chars.first.
|
368
|
+
# Error message (when error occurs) is constructed from
|
369
|
+
# the #try description and the #note strings, which act at
|
370
|
+
# the same time as code comments. End of advertisement for
|
371
|
+
# 'y_support/literate'.
|
372
|
+
#
|
373
|
+
name.to_s.try "to validate the suggested instance name" do
|
374
|
+
note "rejecting non-capitalized names"
|
375
|
+
fail NameError unless ( ?A..?Z ) === chars.first
|
376
|
+
note "rejecting names with spaces"
|
377
|
+
fail NameError if chars.include? ' '
|
378
|
+
end
|
379
|
+
# Return value is the validated name.
|
380
|
+
return name
|
381
|
+
end
|
382
|
+
|
383
|
+
private
|
384
|
+
|
385
|
+
# Searches all modules for user class instances.
|
386
|
+
#
|
387
|
+
def search_all_modules
|
388
|
+
# Set up the list of object ids to search. These are ids
|
389
|
+
# of all unnamed registered instances.
|
390
|
+
todo = ( nameless_instances + __avid_instances__ )
|
391
|
+
.map( &:object_id )
|
392
|
+
.uniq
|
393
|
+
# Browse all modules in the deep ObjectSpace for those ids.
|
394
|
+
ObjectSpace.each_object Module do |ɱ|
|
395
|
+
ɱ.constants( false ).each do |const_ß|
|
396
|
+
# Some constants cause unexpected problems. The line
|
397
|
+
# below is the result of trial-and-error programming
|
398
|
+
# and I am afraid to delete it quite yet.
|
399
|
+
next if ɱ == Object && const_ß == :Config
|
400
|
+
# Those constants that raise certain errors upon attempts
|
401
|
+
# to access their contents are handled by this
|
402
|
+
# begin-rescue-end statement.
|
403
|
+
begin
|
404
|
+
instance = ɱ.const_get( const_ß )
|
405
|
+
rescue LoadError, StandardError
|
406
|
+
next # go on to the next constant
|
407
|
+
end
|
408
|
+
# We now go on to the next iteration of the loop if the
|
409
|
+
# constant which we are checking does not refer to the
|
410
|
+
# object with id we are searching for.
|
411
|
+
next unless todo.include? instance.object_id
|
412
|
+
# At this point, we have ascertained that the constant
|
413
|
+
# we are looking at contains unnamed instance.
|
414
|
+
if instance.avid? then
|
415
|
+
begin
|
416
|
+
# Name it rudely.
|
417
|
+
instance.name! const_ß
|
418
|
+
ensure
|
419
|
+
# Remove the "avid" flag from the instance.
|
420
|
+
instance.make_not_avid!
|
421
|
+
end
|
422
|
+
else
|
423
|
+
# Avid flag is not set, name the instance politely.
|
424
|
+
#
|
425
|
+
# Note that instances of NameMagic user classes are
|
426
|
+
# created avid. So if the anonymous instance is not
|
427
|
+
# avid at this point, it means it must have lost its
|
428
|
+
# avidity either being a previously named and now
|
429
|
+
# unnamed instance, or by the user explicitly invoking
|
430
|
+
# its #make_not_avid! method. In the first case, we do
|
431
|
+
# not want to see NameErrors raised ad infinitum just
|
432
|
+
# because there is some now-unnamed instance assigned
|
433
|
+
# to some forgotten constant in the deep namespace.
|
434
|
+
# In the second case, we must assume that the user
|
435
|
+
# takes the responsibility. So we will swallow NameError
|
436
|
+
# here:
|
437
|
+
begin
|
438
|
+
instance.name = const_ß
|
439
|
+
rescue NameError
|
440
|
+
end
|
441
|
+
end
|
442
|
+
# Remove the instance object id from todo list.
|
443
|
+
todo.delete instance.object_id
|
444
|
+
# Quit looping once todo list is empty.
|
445
|
+
break if todo.empty?
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end # module NameMagic::NamespaceMethods
|