y_support 2.1.18 → 2.4.4
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.
- 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
|