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
data/lib/y_support/name_magic.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative '../y_support'
|
4
|
+
require_relative 'core_ext/hash/misc'
|
5
|
+
require_relative 'literate'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
34
|
-
#
|
35
|
-
#
|
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
|
-
#
|
42
|
-
#
|
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
|
51
|
-
#
|
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
|
-
#
|
116
|
+
# Make the subclasses be their own namespaces with +#namespace!:
|
54
117
|
#
|
55
118
|
# Dog.namespace!
|
56
119
|
#
|
57
|
-
# NameMagic also provides
|
58
|
-
# care of :name (alias :ɴ)
|
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
|
124
|
+
# Dog.new.name = :Rover
|
62
125
|
# Dog.instances._names_ #=> [:Spot, :Rover]
|
63
126
|
# Animal.instances._names_ #=> []
|
64
127
|
#
|
65
|
-
#
|
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
|
-
#
|
68
|
-
#
|
136
|
+
# Dog.forget "Spot"
|
137
|
+
# Dog.forget "Rover"
|
69
138
|
#
|
70
|
-
#
|
71
|
-
#
|
139
|
+
# Spot and Rover show their inspect string for the last time and
|
140
|
+
# are garbage collected.
|
72
141
|
#
|
73
142
|
module NameMagic
|
74
|
-
|
143
|
+
require_relative 'name_magic/array_methods'
|
144
|
+
require_relative 'name_magic/hash_methods'
|
75
145
|
|
76
|
-
|
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
|
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
|
83
|
-
# not defined otherwise when this method is
|
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.
|
87
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
105
|
-
#
|
106
|
-
#
|
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
|
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
|
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
|
-
|
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
|
123
|
-
#
|
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
|
223
|
+
# Retrieves the instance name. Does not trigger #const_magic
|
224
|
+
# before doing so.
|
126
225
|
#
|
127
226
|
def __name__
|
128
|
-
|
129
|
-
namespace.name_get_hook.( ɴ ) if ɴ
|
227
|
+
self.class.__instances__[ self ]
|
130
228
|
end
|
131
229
|
|
132
|
-
# 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
|
-
|
136
|
-
if name.nil?
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
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
|
-
|
154
|
-
return
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
namespace.
|
160
|
-
|
161
|
-
|
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
|
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
|
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
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
#
|
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
|
183
|
-
|
184
|
-
@
|
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
|
-
#
|
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
|
-
#
|
202
|
-
#
|
203
|
-
#
|
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
|
206
|
-
|
207
|
-
#
|
208
|
-
|
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
|
data/lib/y_support/respond_to.rb
CHANGED
@@ -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
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'matrix/misc'
|
data/lib/y_support/stdlib_ext.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'array/typing'
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'enumerable/typing'
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'hash/typing'
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'module/typing'
|