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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/y_support/all.rb +2 -32
  3. data/lib/y_support/core_ext/array.rb +2 -2
  4. data/lib/y_support/core_ext/class.rb +2 -2
  5. data/lib/y_support/core_ext/enumerable.rb +2 -2
  6. data/lib/y_support/core_ext/hash/misc.rb +23 -10
  7. data/lib/y_support/core_ext/hash.rb +2 -2
  8. data/lib/y_support/core_ext/module/misc.rb +9 -0
  9. data/lib/y_support/core_ext/module.rb +2 -2
  10. data/lib/y_support/core_ext/numeric.rb +2 -2
  11. data/lib/y_support/core_ext/object/inspection.rb +8 -2
  12. data/lib/y_support/core_ext/object.rb +3 -3
  13. data/lib/y_support/core_ext/string/misc.rb +9 -12
  14. data/lib/y_support/core_ext/string.rb +2 -2
  15. data/lib/y_support/core_ext/symbol.rb +2 -2
  16. data/lib/y_support/core_ext.rb +1 -1
  17. data/lib/y_support/flex_coerce/class_methods.rb +49 -0
  18. data/lib/y_support/flex_coerce/flex_proxy.rb +121 -0
  19. data/lib/y_support/flex_coerce/module_methods.rb +37 -0
  20. data/lib/y_support/flex_coerce.rb +24 -0
  21. data/lib/y_support/kde.rb +1 -1
  22. data/lib/y_support/literate.rb +253 -0
  23. data/lib/y_support/local_object.rb +1 -1
  24. data/lib/y_support/name_magic/array_methods.rb +48 -0
  25. data/lib/y_support/name_magic/class_methods.rb +205 -161
  26. data/lib/y_support/name_magic/hash_methods.rb +33 -0
  27. data/lib/y_support/name_magic/namespace.rb +449 -0
  28. data/lib/y_support/name_magic.rb +358 -100
  29. data/lib/y_support/null_object.rb +1 -1
  30. data/lib/y_support/respond_to.rb +1 -1
  31. data/lib/y_support/stdlib_ext/matrix/misc.rb +2 -2
  32. data/lib/y_support/stdlib_ext/matrix.rb +2 -2
  33. data/lib/y_support/stdlib_ext.rb +1 -1
  34. data/lib/y_support/typing/array.rb +1 -1
  35. data/lib/y_support/typing/enumerable.rb +1 -1
  36. data/lib/y_support/typing/hash.rb +1 -1
  37. data/lib/y_support/typing/module.rb +1 -1
  38. data/lib/y_support/typing/object/typing.rb +17 -15
  39. data/lib/y_support/typing/object.rb +1 -1
  40. data/lib/y_support/typing.rb +14 -10
  41. data/lib/y_support/unicode.rb +1 -1
  42. data/lib/y_support/version.rb +1 -1
  43. data/lib/y_support/x.rb +2 -1
  44. data/test/flex_coerce_test.rb +134 -0
  45. data/test/literate_test.rb +231 -0
  46. data/test/misc_test.rb +49 -27
  47. data/test/name_magic_test.rb +907 -60
  48. data/test/typing_test.rb +7 -7
  49. metadata +14 -13
  50. data/lib/y_support/abstract_algebra.rb +0 -234
  51. data/lib/y_support/name_magic/array.rb +0 -38
  52. data/lib/y_support/name_magic/hash.rb +0 -31
  53. data/lib/y_support/name_magic/namespace_methods.rb +0 -260
  54. data/lib/y_support/try.rb +0 -133
  55. data/test/abstract_algebra_test.rb +0 -138
  56. data/test/performance_test_example.rb +0 -23
  57. data/test/try_test.rb +0 -102
@@ -1,17 +1,18 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'y_support'
4
- require 'y_support/core_ext/hash/misc'
3
+ require_relative '../y_support'
4
+ require_relative 'core_ext/hash/misc'
5
+ require_relative 'literate'
5
6
 
6
- require_relative 'name_magic/array'
7
- require_relative 'name_magic/hash'
8
-
9
- # This mixin imitates Ruby constant magic and automates the named argument
10
- # :name, alias (Character "ɴ", Unicode small capital N, generally stands
11
- # for "name" ins YSupport). One can write:
7
+ # Module NameMagic imitates Ruby constant magic and automates the
8
+ # named argument :name, alias :ɴ (Character "ɴ", Unicode small
9
+ # capital N). At the same time, NameMagic provides the registry of
10
+ # instances of the user class. In Ruby, we frequently want to keep
11
+ # a list of instances of some classes, and NameMagic also helps
12
+ # with this task. Simple example:
12
13
  #
13
14
  # require 'y_support/name_magic'
14
- # class Foo;
15
+ # class Foo
15
16
  # include NameMagic
16
17
  # end
17
18
  # Bar = Foo.new
@@ -20,78 +21,162 @@ require_relative 'name_magic/hash'
20
21
  #
21
22
  # Bar.name #=> "Bar"
22
23
  #
23
- # This is done by searching whole Ruby namespace for constants, via #const_magic
24
- # defined in the namespace mixin. (Once the object is named, its assignments to
25
- # other constants have no further effects.) By default, the class, in which
26
- # NameMagic is included acts as a namespace: holds a list of instances and their
27
- # names, which is often useful.
24
+ # We can get the list of instances by:
28
25
  #
29
26
  # Foo.instances #=> [Bar]
30
27
  #
31
- # It is possible to set another module as namespace:
28
+ # Additionally, NameMagic provides two hooks: Instantiation hook
29
+ # activates when a new instance is created, and naming hook
30
+ # activates when the created instance is baptized. Let us set the
31
+ # first hook, for example, as follows:
32
32
  #
33
- # Quux = Module.new
34
- # class FooBar
35
- # include NameMagic
33
+ # Foo.instantiation_hook do |instance|
34
+ # puts "New instance of Foo with object id " +
35
+ # "#{instance.object_id} created!"
36
+ # end
37
+ #
38
+ # Now let us set the second hook as follows:
39
+ #
40
+ # Foo.naming_hook do |name, instance|
41
+ # puts "Instance with object id #{instance.object_id} " +
42
+ # "is baptized #{name}!"
43
+ # name
36
44
  # end
37
- # FooBar.namespace = Quux
38
- # FooBar.new name: "Baz"
39
- # Quux.instances #=> [Baz]
40
45
  #
41
- # When subclassing the classes with NameMagic included, namespace setting does
42
- # not change:
46
+ # Note that the naming hook must always return name. (This can be
47
+ # used to censor the name on the fly, but that's beyond this basic
48
+ # intro.) Now that we set the hooks, let us observe when do they
49
+ # activate:
50
+ #
51
+ # i = Foo.new
52
+ # New instance of Foo with object id 73054440 created!
53
+ #
54
+ # Baz = i
55
+ # Instance with object id 73054440 is baptized Baz!
56
+ #
57
+ # We can see that the registry of instances now registers two
58
+ # instances:
59
+ #
60
+ # Foo.instances #=> [Bar, Baz]
61
+ #
62
+ # NameMagic has been programmed to be simple and intuitive to use,
63
+ # so with this little demonstration, you can start using it without
64
+ # fear. You can find the rest of the methods provided by NameMagic
65
+ # in the documentation.
66
+ #
67
+ # However, behind the scenes, inner workings of NameMagic require
68
+ # understanding. The key part of NameMagic is the code that
69
+ # searches Ruby namespace for constants. This search is done
70
+ # automatically when necessary. It can be also explicitly initiated
71
+ # by calling .const_magic class method, but this is rarely
72
+ # needed. When you write "include NameMagic" in some class, three
73
+ # things happen:
74
+ #
75
+ # 1. Module NameMagic is included in that class, as expected.
76
+ # 2. Class is extended with NameMagic::ClassMethods.
77
+ # 3. Namespace is extended with NameMagic::NamespaceMethods.
78
+ #
79
+ # Namespace (in the NameMagic sense) is a module that holds the
80
+ # list of instances and their names. Typically, the user class acts
81
+ # as its own namespace. Note that the meaning of the word
82
+ # 'namespace' is somewhat different from its meaning in general
83
+ # Ruby. NameMagic actually provides class method .namespace that
84
+ # returns the namespace of the class. Consider this example:
85
+ #
86
+ # require 'y_support/name_magic'
87
+ # class Animal
88
+ # include NameMagic
89
+ # end
90
+ # Animal.namespace #=> Animal
91
+ #
92
+ # We can see that the namespace of Animal class is again Animal
93
+ # class. But when we subclass it:
43
94
  #
44
- # class Animal; include NameMagic end
45
95
  # class Dog < Animal; end
46
96
  # class Cat < Animal; end
47
97
  # Dog.namespace #=> Animal
48
98
  # Cat.namespace #=> Animal
99
+ #
100
+ # The subclasses retain Animal as their namespace. Let us continue
101
+ # with the example:
102
+ #
49
103
  # Livia = Cat.new
50
- # Cat.instances._names_ #=> []
51
- # Animal.instances._names_ #=> [:Livia]
104
+ # Cat.instances #=> [Livia]
105
+ # Dog.instances #=> []
106
+ # Animal.instances #=> [Livia]
107
+ #
108
+ # Let us demonstrate alternative ways of creating named objects:
109
+ #
110
+ # Dog.new name: :Spot
111
+ # Dog.new ɴ: "Rover"
112
+ # Cat.instances #=> [Livia]
113
+ # Dog.instances #=> [Spot, Rover]
114
+ # Animal.instances #=> [Livia, Spot, Rover]
52
115
  #
53
- # To make the subclasses use each their own namespace, use +#namespace!+ method:
116
+ # Make the subclasses be their own namespaces with +#namespace!:
54
117
  #
55
118
  # Dog.namespace!
56
119
  #
57
- # NameMagic also provides an alternative way to create named objects by taking
58
- # care of :name (alias :ɴ) named argument of the constructor:
120
+ # NameMagic also provides another way of naming objects by taking
121
+ # care of :name (alias :ɴ) parameter of #new constructor:
59
122
  #
60
123
  # Dog.new name: "Spot"
61
- # Dog.new ɴ: :Rover
124
+ # Dog.new.name = :Rover
62
125
  # Dog.instances._names_ #=> [:Spot, :Rover]
63
126
  # Animal.instances._names_ #=> []
64
127
  #
65
- # Lastly, a name can be assigned by #name= accssor, as in
128
+ # Note that the Dog instances above did not disappear even though
129
+ # we did not assign them to any variables or constants. This is
130
+ # because the instances of the classes using NameMagic, whether
131
+ # named or not, are since their creation referred to from the
132
+ # instance registry, which prevents them from being garbage
133
+ # collected. To get rid of Spot and Rover, we would have to delete
134
+ # them from the instance registry:
66
135
  #
67
- # <tt>o = SomeClass.new</tt>
68
- # <tt>o.name = "SomeName"</tt>
136
+ # Dog.forget "Spot"
137
+ # Dog.forget "Rover"
69
138
  #
70
- # Hook is provided for when the name magic is performed, as well as when the
71
- # name is retrieved.
139
+ # Spot and Rover show their inspect string for the last time and
140
+ # are garbage collected.
72
141
  #
73
142
  module NameMagic
74
- DEBUG = false
143
+ require_relative 'name_magic/array_methods'
144
+ require_relative 'name_magic/hash_methods'
75
145
 
76
- require_relative 'name_magic/namespace_methods'
146
+ Array.class_exec { include ArrayMethods }
147
+ Hash.class_exec { include HashMethods }
148
+
149
+ require_relative 'name_magic/namespace'
77
150
  require_relative 'name_magic/class_methods'
78
151
 
79
152
  def self.included target
80
- if target.is_a? Class then # decorate #new
153
+ if target.is_a? Class then
154
+ # Define target.namespace method.
81
155
  target.singleton_class.class_exec do
82
- # Primer that sets the namespace of the class to self if the user has
83
- # not defined otherwise when this method is first called.
156
+ # Primer that sets the namespace of the class to self if
157
+ # the user has not defined otherwise when this method is
158
+ # first called.
84
159
  #
85
160
  define_method :namespace do
86
- target.extend ::NameMagic::NamespaceMethods
87
- define_singleton_method :namespace do target end # redefines itself
161
+ # The method first extends target with Namespace methods.
162
+ target.extend NameMagic::Namespace
163
+ # The method then redefines itself.
164
+ define_singleton_method :namespace do target end
165
+ # And finally calls the redefined version of itself.
88
166
  namespace
89
167
  end
90
168
  end
91
- target.singleton_class.class_exec { prepend ::NameMagic::ClassMethods }
92
- else # it is a Module -- infect it with this #include
93
- orig, this = target.method( :included ), method( :included )
94
- target.define_singleton_method :included do |m| this.( m ); orig.( m ) end
169
+ # Prepend NameMagic::ClassMethod to class << target.
170
+ target.singleton_class.class_exec do
171
+ prepend NameMagic::ClassMethods
172
+ end
173
+ else # Target is a Module, infect it with this #include
174
+ original_included_method = target.method :included
175
+ this_method = method :included
176
+ target.define_singleton_method :included do |target|
177
+ this_method.( target )
178
+ original_included_method.( target )
179
+ end
95
180
  end
96
181
  end # self.included
97
182
 
@@ -101,67 +186,143 @@ module NameMagic
101
186
  self.class.namespace
102
187
  end
103
188
 
104
- # Retrieves the instance's name not prefixed by the namespace as a symbol.
105
- # Underlines (+#_name_+) distinguish this method from +#name+ method, which
106
- # returns full name string for compatibility with vanilla Ruby +Module#name+.
189
+ # Retrieves the demodulized instance's name as a symbol.
190
+ # "Demodulized" means that if the full name is "Foo::Bar", only
191
+ # :Bar is returned. Underlines (+#_name_+) distinguish this
192
+ # method from +#name+ method, which returns full name string for
193
+ # compatibility with vanilla Ruby +Module#name+.
107
194
  #
108
195
  def _name_
109
196
  self.class.const_magic
110
197
  __name__ or ( yield self if block_given? )
111
198
  end
112
199
  alias ɴ _name_
113
- # FIXME: Delete the line below! Do it! Make #name return #full_name, as compatible with Class#name behavior!!!
200
+ # FIXME: Delete the line below! Do it! Make #name return
201
+ # #full_name, as compatible with Class#name behavior!!!
114
202
  alias name _name_
115
203
 
116
- # Returns the instance's full name, a string in the style of those returned
117
- # by +Module#name+ method, eg. "Namespace::Name".
204
+ # Returns the instance's full name, a string in the style of
205
+ # those returned by +Module#name+ method, eg. "Namespace::Name".
118
206
  #
119
207
  def full_name
120
- "#{namespace.name || namespace.inspect}::#{namespace.instances[ self ]}"
208
+ # FIXME: This method cannot work until Namespace#const_magic
209
+ # starts noticing not just constant names, as it does now,
210
+ # but also names of the modules those constants are in. This
211
+ # is no simple task.
212
+ #
213
+ # The code below is the closest approximation, yet still
214
+ # patently wrong.
215
+ [ namespace.name || namespace.inspect,
216
+ namespace.instances[ self ]
217
+ ].join "::"
121
218
  end
122
- # FIXME: Uncomment the line below! Do it! Make #name return #full_name, as compatible with Class#name behavior!!!
123
- # alias name full_name
219
+ # FIXME: Uncomment the line below! Do it! Make #name return
220
+ # #full_name, as compatible with Class#name behavior!!! alias
221
+ # name full_name
124
222
 
125
- # Retrieves the instance name. Does not trigger #const_magic before doing so.
223
+ # Retrieves the instance name. Does not trigger #const_magic
224
+ # before doing so.
126
225
  #
127
226
  def __name__
128
- ɴ = self.class.__instances__[ self ]
129
- namespace.name_get_hook.( ɴ ) if ɴ
227
+ self.class.__instances__[ self ]
130
228
  end
131
229
 
132
- # Names an instance, cautiously (ie. no overwriting of existing names).
230
+ # Names the receiver, while rejecting names already in use by
231
+ # another instance. If nil is supplied as an argument, unnames
232
+ # the instance. (This method does not trigger const_magic.)
133
233
  #
134
234
  def name=( name )
135
- old_ɴ = namespace.__instances__[ self ] # previous name
136
- if name.nil? then
137
- namespace.__instances__.update( self => nil ) # unname in @instances
138
- namespace.send :remove_const, old_ɴ if old_ɴ # remove namespace const.
139
- else
140
- ɴ = honor_name_set_hooks( name, old_ɴ )
141
- return if old_ɴ == ɴ # already named as required
142
- fail NameError, "Name '#{ɴ}' already exists in #{namespace} namespace!" if
143
- self.class.__instances__.rassoc( ɴ )
144
- namespace.__forget__ old_ɴ # forget the old name of self
145
- namespace.const_set ɴ, self # write a constant
146
- namespace.__instances__[ self ] = ɴ # write to @instances
147
- end
235
+ # If the argument is nil, the method performs unnaming.
236
+ return unname! if name.nil?
237
+ # Otherwise, the method performs naming the instance, while
238
+ # avoiding stealing names already in use by another instance.
239
+ # Let us look at the current name of the instance first.
240
+ previous_name = namespace.__instances__[ self ]
241
+ # Honor class'es #exec_when_naming hook.
242
+ requested_new_name = honor_exec_when_naming( name )
243
+ # Return if the instance is already named as requested.
244
+ return if previous_name == requested_new_name
245
+ # Raise error if the requested name is already taken.
246
+ self.class.__instances__.rassoc( requested_new_name ) and
247
+ fail NameError, "Name '#{requested_new_name}' already " +
248
+ "exists in #{namespace} namespace!"
249
+ # Now it is sure that the instance will be named, so it does
250
+ # not need to be avid.
251
+ make_not_avid!
252
+ # Rename self by modifying the registry.
253
+ namespace.__instances__.update self => requested_new_name
254
+ # Honor instance's #exec_when_named hook.
255
+ honor_exec_when_named
148
256
  end
149
257
 
150
- # Names an instance, aggresively (overwrites existing names).
258
+ # Names the receiver aggresively. "Aggresively" means that in
259
+ # case the requested new name of the instance is already in use
260
+ # by another instance, the other instance is unnamed. In other
261
+ # words, in case of conflict of a name, the name is stolen from
262
+ # the conflicting instance, which becomes unnamed as a result.
263
+ # (The method does not trigger const_magic.)
151
264
  #
152
265
  def name!( name )
153
- old_ɴ = namespace.__instances__[ self ] # previous name
154
- return self.name = nil if name.nil? # no collider concerns
155
- ɴ = honor_name_set_hooks( name, old_ɴ )
156
- return false if old_ɴ == ɴ # already named as required
157
- pair = namespace.__instances__.rassoc( ɴ )
158
- namespace.__forget__( pair[0] ) if pair # rudely forget the collider
159
- namespace.__forget__ old_ɴ # forget the old name of self
160
- namespace.const_set ɴ, self # write a constant
161
- namespace.__instances__[ self ] = ɴ # write to @instances
266
+ # If the argument is nil, the method performs unnaming.
267
+ return unname! if name.nil?
268
+ # Otherwise, the method performs aggresive naming the instance,
269
+ # where "aggresive" means that in case of conflict over a name,
270
+ # the name is stolen from the conflicting instance.
271
+ # Let us look at the current name of the instance first.
272
+ previous_name = namespace.__instances__[ self ]
273
+ # Honor class'es #exec_when_naming hook.
274
+ requested_new_name = honor_exec_when_naming( name )
275
+ # Return if the instance is already named as requested.
276
+ return if previous_name == requested_new_name
277
+ # See if the requested name is already taken.
278
+ colliding_entry =
279
+ namespace.__instances__.rassoc( requested_new_name )
280
+ # Unname the colliding instance, if any.
281
+ begin
282
+ colliding_entry.first.unname! if colliding_entry
283
+ ensure
284
+ # Unnaming the colliding instance may fail. But whether it
285
+ # fails or succeeds, self must quit being avid. If the
286
+ # unnaming succeeded, self is getting a new name and thus
287
+ # no longer needs to be avid. However, if the unnaming
288
+ # raises an error, we want to avoid seeing the same error
289
+ # over and over again just because avid self assigned to
290
+ # a constant with conflicting name tries over and over again
291
+ # to perform the impossible feat of stealing that name.
292
+ make_not_avid!
293
+ end
294
+ # Rename self by modifying the registry.
295
+ namespace.__instances__.update self => requested_new_name
296
+ # Honor instance's #exec_when_named hook.
297
+ honor_exec_when_named
298
+ # Return the receiver.
299
+ return self
300
+ end
301
+
302
+ # Unnames the instance. Does not trigger #const_magic.
303
+ #
304
+ def unname!
305
+ # Get the current name of the instance.
306
+ name = namespace.__instances__[ self ]
307
+ # If the instance is anonymous, we are done.
308
+ return if name.nil?
309
+ # Check whether unnaming instances is allowed at all.
310
+ fail NameError, "Unnaming and naming by a name already in " +
311
+ "use by another instance has been disallowed!" unless
312
+ unnaming_allowed?
313
+ # Honor class'es #exec_when_unnaming hook.
314
+ honor_exec_when_unnaming
315
+ # Unname the instance by deleting the name from the registry.
316
+ namespace.__instances__.update( self => nil )
317
+ # Honor instance's #exec_when_unnamed hook.
318
+ honor_exec_when_unnamed
319
+ # Return value is the previous name.
320
+ return name
162
321
  end
163
322
 
164
- # Is the instance avid for a name? (Will it overwrite other instance names?)
323
+ # Is the instance avid? ("Avid" means that the instance is so
324
+ # eager to get a name that it will use name even if this is
325
+ # already in use by another instance.)
165
326
  #
166
327
  def avid?
167
328
  namespace.__avid_instances__.any? &method( :equal? )
@@ -170,21 +331,48 @@ module NameMagic
170
331
  # Make the instance not avid.
171
332
  #
172
333
  def make_not_avid!
173
- namespace.__avid_instances__.delete_if { |i| i.object_id == object_id }
334
+ namespace.__avid_instances__.delete_if { |i| equal? i }
335
+ return nil
336
+ end
337
+
338
+ # Is unnaming of the instance allowed? Note: This method just
339
+ # relies on class'es .permanent_names? method. Unnaming is not
340
+ # allowed when .permanent_names? is true.
341
+ #
342
+ def unnaming_allowed?
343
+ ! self.class.permanent_names?
344
+ end
345
+
346
+ # Registers a block to execute as soon as the instance is named.
347
+ # (In other words, this method provides instance's naming hook.)
348
+ # The block is executed in the context of the instance. Return
349
+ # value of the block is unimportant. If no block is given, the
350
+ # method returns the previously defined block, if any, or a
351
+ # default block that does nothing.
352
+ #
353
+ def exec_when_named &block
354
+ @exec_when_named = block if block
355
+ @exec_when_named ||= -> { }
174
356
  end
357
+ # Note: This alias must stay while the dependencies need it.
358
+ alias name_set_hook exec_when_named
175
359
 
176
- # Registers a hook to execute upon instance naming. Instance's `#name_set_hook`
177
- # Behaves analogically as namespace's `#name_set_hook`, and is executed right
178
- # after the namespace's hook. Expects a block with a single argument, name of
179
- # the instance. The return value of the block is not used and should be _nil_.
180
- # Without a block, this method acts as a getter.
360
+ # Registers a block to execute right after the instance is
361
+ # unnamed. (In other words, this method provides instance's
362
+ # unnaming hook.) The block is executed in the context of the
363
+ # instance. Return value of the block is unimportant. If no block
364
+ # is given, the method returns the previously defined block, if
365
+ # any, or a default block that does nothing.
181
366
  #
182
- def name_set_hook &block
183
- tap { @name_set_hook = block } if block
184
- @name_set_hook ||= -> name { nil }
367
+ def exec_when_unnamed &block
368
+ @exec_when_unnamed = block if block
369
+ @exec_when_unnamed ||= -> { }
185
370
  end
371
+ # Note: This alias must stay while the dependencies need it.
372
+ alias name_set_hook exec_when_named
186
373
 
187
- # Default +#to_s+ method for +NameMagic+ includers, returning the name.
374
+ # +NameMagic+ redefines #to_s method to show names.
375
+ # name.
188
376
  #
189
377
  def to_s
190
378
  name ? name.to_s : super
@@ -198,13 +386,83 @@ module NameMagic
198
386
 
199
387
  private
200
388
 
201
- # Honors name set hooks, first for the namespace, then for the instance.
202
- # Takes 2 arguments, name and old name of this instance. Returns the final
203
- # name to be used
389
+ # Make the instance avid. Does not trigger const_magic. (Remark:
390
+ # Invoking this method on named instances is considered gross
391
+ # indecency.)
392
+ #
393
+ def make_avid!
394
+ namespace.__avid_instances__ << self unless
395
+ namespace.__avid_instances__.include? self
396
+ return nil
397
+ end
398
+
399
+ # Honors the class'es hook #exec_when_naming. Takes 2
400
+ # arguments, name and old name of this instance. Also calls
401
+ # Namespace#validate_name method. Returns the final name to be
402
+ # used.
403
+ #
404
+ def honor_exec_when_naming( suggested_name )
405
+ instance = self
406
+ previous_name = namespace.__instances__[ instance ]
407
+ suggested_name = suggested_name.to_s
408
+ # Calling exec_when_naming without a block makes the method
409
+ # return the block defined earlier.
410
+ block = self.class.exec_when_naming
411
+ # Execute the namespace hook in the context of the user class.
412
+ name = self.class.instance_exec( suggested_name,
413
+ instance,
414
+ previous_name,
415
+ &block )
416
+ # The hook is supposed to return the name to be actually used.
417
+ # But if the user used the block for other purposes and did
418
+ # not bother to return a string or symbol (or anything that
419
+ # can be converted to a symbol), we will assume that the user
420
+ # meant to leave the suggested name without intervention.
421
+ # I wonder whether this behavior is too smart.
422
+ name = begin; name.to_sym; rescue NoMethodError
423
+ suggested_name
424
+ end
425
+ # Finally, apply validate_name method and return the result.
426
+ return self.class.validate_name( name ).to_sym
427
+ end
428
+
429
+ # Honors instance's hook #exec_when_named.
430
+ #
431
+ def honor_exec_when_named
432
+ # Method #exec_when_named, when called without a block, returns
433
+ # the block defined earlier.
434
+ block = exec_when_named
435
+ # Block is executed within the context of this instance.
436
+ instance_exec &block
437
+ # The method returns nil.
438
+ return nil
439
+ end
440
+
441
+ # Honors the class'es hook #exec_when_unnaming.
442
+ #
443
+ def honor_exec_when_unnaming
444
+ instance = self
445
+ previous_name = namespace.__instances__[ instance ]
446
+ # Calling exec_when_unnaming without a block makes the method
447
+ # return the block defined earlier.
448
+ block = self.class.exec_when_unnaming
449
+ # Execute the namespace hook in the context of the user class.
450
+ name = self.class.instance_exec( instance,
451
+ previous_name,
452
+ &block )
453
+ # The method returns nil.
454
+ return nil
455
+ end
456
+
457
+ # Honors instance's hook #exec_when_unnamed.
204
458
  #
205
- def honor_name_set_hooks suggested_name, old_name
206
- ɴ = namespace.name_set_hook.( suggested_name, self, old_name ).to_sym
207
- # puts "NameMagic: Name adjusted to #{name}." if DEBUG
208
- namespace.validate_name( ɴ ).to_sym.tap { |ɴ| name_set_hook.( ɴ ) }
459
+ def honor_exec_when_unnamed
460
+ # Method #exec_when_unnamed, when called without a block,
461
+ # returns the block defined earlier.
462
+ block = exec_when_unnamed
463
+ # Block is executed within the context of this instance.
464
+ instance_exec &block
465
+ # The method returns nil.
466
+ return nil
209
467
  end
210
468
  end # module NameMagic
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'y_support'
3
+ require_relative '../y_support'
4
4
 
5
5
  # Null object pattern implementation in +YSupport+. apart from the expected null
6
6
  # object behavior (such as returning self in response to almost all messages),
@@ -1,4 +1,4 @@
1
- require 'y_support'
1
+ require_relative '../y_support'
2
2
 
3
3
  # RespondTo class for easy use of respond_to? in case statements.
4
4
  #
@@ -5,7 +5,7 @@ class Matrix
5
5
  def pretty_inspect
6
6
  return inspect if row_size == 0 or column_size == 0
7
7
  aa = send( :rows ).each.with_object [] do |row, memo|
8
- memo << row.map{ |o|
8
+ memo << row.map { |o|
9
9
  os = o.to_s
10
10
  case o
11
11
  when Numeric then os[0] == '-' ? os : ' ' + os
@@ -18,7 +18,7 @@ class Matrix
18
18
  memo << "\n"
19
19
  end
20
20
  end
21
-
21
+
22
22
  # Pretty print
23
23
  def pretty_print
24
24
  print pretty_inspect
@@ -1,2 +1,2 @@
1
- require 'y_support' unless defined? YSupport
2
- require File.dirname( __FILE__ ) + '/matrix/misc'
1
+ require_relative '../../y_support'
2
+ require_relative 'matrix/misc'
@@ -1,4 +1,4 @@
1
1
  Dir["#{File.dirname( __FILE__ )}/stdlib_ext/*.rb"].sort.each do |path|
2
- require "y_support/stdlib_ext/#{File.basename( path, '.rb' )}"
2
+ require_relative "y_support/stdlib_ext/#{File.basename( path, '.rb' )}"
3
3
  end
4
4
 
@@ -1 +1 @@
1
- require File.dirname( __FILE__ ) + '/array/typing'
1
+ require_relative 'array/typing'
@@ -1 +1 @@
1
- require File.dirname( __FILE__ ) + '/enumerable/typing'
1
+ require_relative 'enumerable/typing'
@@ -1 +1 @@
1
- require File.dirname( __FILE__ ) + '/hash/typing'
1
+ require_relative 'hash/typing'
@@ -1 +1 @@
1
- require File.dirname( __FILE__ ) + '/module/typing'
1
+ require_relative 'module/typing'