y_support 1.1.0 → 2.0.0
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/local_object.rb +10 -6
- data/lib/y_support/misc.rb +0 -1
- data/lib/y_support/name_magic.rb +50 -76
- data/lib/y_support/version.rb +1 -1
- data/lib/y_support.rb +2 -30
- data/test/misc_test.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 759b0ff1cab2ec03f748370b5cf7914ba85fffd7
|
4
|
+
data.tar.gz: 05aa1789b0a44fac0e98a7e3f1be9dc9bd77e726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ce6a5309f0d05cfc049bc2ad4264465e05a41320863257e318a15895a3f7e33608e90d2c479305d05120073e351446404130c9989d6f870f9f0f64de99e4b81
|
7
|
+
data.tar.gz: 458aa7e250fc6e902e6943fd6d74cd5a49ffe3ef84b334f62022fb3d8b19750b0393109f6fa4ad28a29ffa8018ee30750c9a2012d4f1170b3e8899bb955a2326
|
@@ -4,7 +4,7 @@ require 'y_support'
|
|
4
4
|
|
5
5
|
# Object, whose business is to stay local to methods. Optional signature
|
6
6
|
# provides additional level of safety in ensuring object locality. (Signature
|
7
|
-
# accessor is :signature, aliased as
|
7
|
+
# accessor is :signature, aliased as :σ, small Greek sigma.)
|
8
8
|
#
|
9
9
|
class LocalObject
|
10
10
|
attr_reader :signature
|
@@ -13,23 +13,27 @@ class LocalObject
|
|
13
13
|
# Optional argument signature provides additional level of safety in
|
14
14
|
# ascertaining that the object indeed is of local origin.
|
15
15
|
#
|
16
|
-
def initialize signature=
|
17
|
-
@signature=signature
|
16
|
+
def initialize signature=caller_locations( 1, 1 )[0].label
|
17
|
+
@signature = signature
|
18
18
|
end
|
19
19
|
|
20
20
|
# True if the (optional) signature matches.
|
21
21
|
#
|
22
|
-
def local_object? signature=
|
22
|
+
def local_object? signature=caller_locations( 1, 1 )[0].label
|
23
23
|
signature == self.signature
|
24
24
|
end
|
25
25
|
alias ℓ? local_object?
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
# Object class is patched with #LocalObject (alias L!) constructor, and
|
29
|
+
# #local_object?, alias #ℓ? inquirer.
|
30
|
+
#
|
29
31
|
class Object
|
30
32
|
# LocalObject constructor.
|
31
33
|
#
|
32
|
-
def LocalObject signature=
|
34
|
+
def LocalObject signature=caller_locations( 1, 1 )[0].label
|
35
|
+
LocalObject.new signature
|
36
|
+
end
|
33
37
|
alias L! LocalObject
|
34
38
|
|
35
39
|
# False for normal objects, overriden in the LocalObject class.
|
data/lib/y_support/misc.rb
CHANGED
data/lib/y_support/name_magic.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
require 'y_support'
|
3
3
|
|
4
4
|
# A mixin imitating Ruby constant magic, plus automation of :name alias :ɴ
|
@@ -24,23 +24,20 @@ require 'y_support'
|
|
24
24
|
#
|
25
25
|
module NameMagic
|
26
26
|
DEBUG = false
|
27
|
-
PROBLEM_MODULES = [ 'Gem', 'Rack', 'ActiveSupport' ]
|
28
27
|
|
29
28
|
def self.included target
|
30
29
|
case target
|
31
|
-
when Class then
|
30
|
+
when Class then # we will decorate its #new method
|
32
31
|
class << target
|
33
|
-
# Make space
|
34
|
-
alias :original_method_new :new
|
32
|
+
alias :original_method_new :new # Make space to decorate #new
|
35
33
|
end
|
36
34
|
# Attach the decorators etc.
|
37
35
|
target.extend ::NameMagic::ClassMethods
|
38
36
|
target.extend ::NameMagic::NamespaceMethods
|
39
37
|
# Attach namespace methods to also to the namespace, if given.
|
40
38
|
begin
|
41
|
-
|
42
|
-
target.namespace
|
43
|
-
end
|
39
|
+
target.namespace.extend ::NameMagic::NamespaceMethods unless
|
40
|
+
target.namespace == target
|
44
41
|
rescue NoMethodError
|
45
42
|
end
|
46
43
|
else # it is a Module; we'll infect it with this #included method
|
@@ -50,13 +47,13 @@ module NameMagic
|
|
50
47
|
target.method( :pre_included )
|
51
48
|
rescue NameError
|
52
49
|
end
|
53
|
-
if pre_included_of_the_target then
|
50
|
+
if pre_included_of_the_target then # target has #pre_included hook
|
54
51
|
target.define_singleton_method :included do |ç|
|
55
52
|
pre_included_of_the_target.( ç )
|
56
53
|
included_of_self.call( ç )
|
57
54
|
included_of_the_target.call( ç )
|
58
55
|
end
|
59
|
-
else
|
56
|
+
else # target has no #pre_included hook
|
60
57
|
target.define_singleton_method :included do |ç|
|
61
58
|
included_of_self.( ç )
|
62
59
|
included_of_the_target.( ç )
|
@@ -101,8 +98,7 @@ module NameMagic
|
|
101
98
|
# Names an instance, aggresively (overwrites existing names).
|
102
99
|
#
|
103
100
|
def name!( ɴ )
|
104
|
-
|
105
|
-
old_ɴ = self.class.__instances__[ self ]
|
101
|
+
old_ɴ = self.class.__instances__[ self ] # get instance's old name, if any
|
106
102
|
# honor the hook
|
107
103
|
name_set_closure = self.class.instance_variable_get :@name_set_closure
|
108
104
|
ɴ = name_set_closure.( ɴ, self, old_ɴ ) if name_set_closure
|
@@ -111,7 +107,7 @@ module NameMagic
|
|
111
107
|
# otherwise, rudely remove the collider, if any
|
112
108
|
pair = self.class.__instances__.rassoc( ɴ )
|
113
109
|
self.class.__forget__( pair[0] ) if pair
|
114
|
-
# and add
|
110
|
+
# and add self to the namespace instead
|
115
111
|
self.class.namespace.const_set ɴ, self # write a constant
|
116
112
|
self.class.__instances__[ self ] = ɴ # write to __instances__
|
117
113
|
self.class.__forget__ old_ɴ # forget the old name of self
|
@@ -155,10 +151,10 @@ module NameMagic
|
|
155
151
|
self
|
156
152
|
end
|
157
153
|
|
158
|
-
# Returns
|
159
|
-
# argument
|
160
|
-
#
|
161
|
-
#
|
154
|
+
# Returns an instance identiified by the argument. NameError is raised, if
|
155
|
+
# the argument does not identify an instance. (It can be an instance name
|
156
|
+
# as string, symbol, or an instance itself, in which case it is merely
|
157
|
+
# returned without changes.)
|
162
158
|
#
|
163
159
|
def instance arg
|
164
160
|
const_magic
|
@@ -224,7 +220,7 @@ module NameMagic
|
|
224
220
|
}
|
225
221
|
end
|
226
222
|
alias :forget_nameless_instances :forget_anonymous_instances
|
227
|
-
|
223
|
+
|
228
224
|
# Clears class-owned references to all the instances.
|
229
225
|
#
|
230
226
|
def forget_all_instances
|
@@ -261,35 +257,22 @@ module NameMagic
|
|
261
257
|
# Checks all the constants in some module's namespace, recursively.
|
262
258
|
#
|
263
259
|
def serve_all_modules
|
264
|
-
|
265
|
-
|
266
|
-
ObjectSpace.each_object Module do |ɱ|
|
267
|
-
# hack against bugs when getting constants from URI
|
268
|
-
next if ::NameMagic::PROBLEM_MODULES.any? { |problem_ς|
|
269
|
-
begin
|
270
|
-
ɱ.name.to_s.start_with? problem_ς
|
271
|
-
rescue NoMethodError, ArgumentError
|
272
|
-
end
|
273
|
-
}
|
260
|
+
todo = ( nameless_instances + __avid_instances__ ).map( &:object_id ).uniq
|
261
|
+
ObjectSpace.each_object Module do |ɱ| # for all the modules...
|
274
262
|
puts ɱ if ::NameMagic::DEBUG
|
275
|
-
#
|
276
|
-
|
277
|
-
begin # insurance against buggy dynamic loading of constants
|
263
|
+
ɱ.constants( false ).each do |const_ß| # and all the constants...
|
264
|
+
begin # insurance against constant dynamic loading fails
|
278
265
|
◉ = ɱ.const_get( const_ß )
|
279
|
-
rescue
|
266
|
+
rescue LoadError, StandardError
|
280
267
|
next
|
281
268
|
end
|
282
|
-
# is it a wanted object?
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
◉.name! const_ß # and then name it rudely
|
290
|
-
else # name this anonymous instance cautiously
|
291
|
-
# honor name_set_closure
|
292
|
-
ɴ = if @name_set_closure then
|
269
|
+
if todo.include? ◉.object_id then # is it a wanted object?
|
270
|
+
if __avid_instances__.map( &:object_id ).include? ◉.object_id # avid
|
271
|
+
__avid_instances__ # 1. remove from avid list
|
272
|
+
.delete_if { |instance| instance.object_id == ◉.object_id }
|
273
|
+
◉.name! const_ß # 2. name rudely
|
274
|
+
else # not avid
|
275
|
+
ɴ = if @name_set_closure then # honor name_set_closure
|
293
276
|
@name_set_closure.( const_ß, ◉, nil )
|
294
277
|
else const_ß end
|
295
278
|
ɴ = validate_capitalization( ɴ ).to_sym
|
@@ -301,14 +284,12 @@ module NameMagic
|
|
301
284
|
raise NameError, "Another #{self} named '#{ɴ}' already " +
|
302
285
|
"exists!" unless conflicter == ◉
|
303
286
|
else
|
304
|
-
# add the instance to the namespace
|
305
|
-
|
306
|
-
namespace.const_set ɴ, ◉
|
287
|
+
__instances__[ ◉ ] = ɴ # add the instance to the namespace
|
288
|
+
namespace.const_set ɴ, ◉ # add the instance to the namespace
|
307
289
|
end
|
308
290
|
end
|
309
|
-
|
310
|
-
|
311
|
-
break if incriminated_ids.empty?
|
291
|
+
todo.delete ◉.object_id # remove the id from todo list
|
292
|
+
break if todo.empty?
|
312
293
|
end
|
313
294
|
end # each
|
314
295
|
end # each_object Module
|
@@ -316,7 +297,7 @@ module NameMagic
|
|
316
297
|
|
317
298
|
# Checks whether a name starts with a capital letter.
|
318
299
|
#
|
319
|
-
def validate_capitalization
|
300
|
+
def validate_capitalization name
|
320
301
|
ɴ = name.to_s
|
321
302
|
# check whether the name starts with 'A'..'Z'
|
322
303
|
raise NameError, "#{self.class} name must start with a capital " +
|
@@ -326,48 +307,41 @@ module NameMagic
|
|
326
307
|
end
|
327
308
|
|
328
309
|
module ClassMethods
|
329
|
-
# In addition to
|
330
|
-
#
|
331
|
-
#
|
332
|
-
#
|
310
|
+
# In addition to 'constant magic' ability (name upon constant assignment),
|
311
|
+
# NameMagic redefines class method #new so that it eats parameter :name,
|
312
|
+
# alias :ɴ, and takes care of naming the instance accordingly. Option
|
313
|
+
# :name_avid can also be supplied (true/false), which makes the naming
|
314
|
+
# avid if true. (Avid, or aggresive naming means that the instance being
|
315
|
+
# named overwrites whatever was stored under that name earlier.)
|
333
316
|
#
|
334
317
|
def new *args, &block
|
335
318
|
oo = args[-1].is_a?( Hash ) ? args.pop : {} # extract hash
|
336
|
-
|
337
|
-
|
338
|
-
elsif oo[:ɴ] then oo.delete :ɴ
|
319
|
+
ɴß = if oo[:name] then oo.delete :name # consume :name if supplied
|
320
|
+
elsif oo[:ɴ] then oo.delete :ɴ # consume :ɴ if supplied
|
339
321
|
else nil end
|
340
|
-
|
341
|
-
|
342
|
-
# Avoid name collisions unless avid
|
322
|
+
avid = oo[:name_avid] ? oo.delete( :name_avid ) : false # => true/false
|
323
|
+
# Avoid overwriting existing names unless avid:
|
343
324
|
raise NameError, "#{self} instance #{ɴß} already exists!" if
|
344
325
|
__instances__.keys.include? ɴß unless avid
|
345
|
-
#
|
326
|
+
# Instantiate:
|
346
327
|
args << oo unless oo.empty? # fuse hash
|
347
328
|
new_inst = original_method_new *args, &block
|
348
|
-
|
349
|
-
__instances__.merge! new_inst => nil
|
329
|
+
__instances__.merge! new_inst => nil # Instance is created unnamed
|
350
330
|
# honor the hook
|
351
|
-
@new_instance_closure.
|
352
|
-
|
353
|
-
# (avid instances will steal names from their competitors)
|
354
|
-
if ɴß then
|
331
|
+
@new_instance_closure.( new_inst ) if @new_instance_closure
|
332
|
+
if ɴß then # name was supplied, name the instance
|
355
333
|
if avid then new_inst.name! ɴß else new_inst.name = ɴß end
|
356
|
-
else
|
334
|
+
else # name wasn't supplied, make the instance avid
|
357
335
|
__avid_instances__ << new_inst
|
358
336
|
end
|
359
|
-
# return the new instance
|
360
|
-
return new_inst
|
337
|
+
return new_inst # return the new instance
|
361
338
|
end
|
362
339
|
|
363
|
-
#
|
364
|
-
# concerns about overwriting existing named instances.
|
340
|
+
# Calls #new in avid mode (name_avid: true).
|
365
341
|
#
|
366
342
|
def new! *args, &block
|
367
|
-
# extract options
|
368
|
-
|
369
|
-
# and call #new with added name_avid: true
|
370
|
-
new *args, oo.merge!( name_avid: true )
|
343
|
+
oo = args[-1].is_a?( Hash ) ? args.pop : {} # extract options
|
344
|
+
new *args, oo.merge!( name_avid: true ), &block
|
371
345
|
end
|
372
346
|
end # module ClassMethods
|
373
347
|
end # module NameMagic
|
data/lib/y_support/version.rb
CHANGED
data/lib/y_support.rb
CHANGED
@@ -1,33 +1,5 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
# What follows is a commented-out list of interesting StdLibs. They may
|
6
|
-
# or may no be required in various parts of y_support.
|
3
|
+
# YSupport is a collection of methods used in Y gems.
|
7
4
|
#
|
8
|
-
|
9
|
-
# require 'mathn'
|
10
|
-
# require 'set'
|
11
|
-
# require 'csv'
|
12
|
-
|
13
|
-
# What follows is a commented-out list of interesting ActiveSupport parts.
|
14
|
-
# These may or may not be required in various parts of y_support.
|
15
|
-
#
|
16
|
-
# require 'active_support/core_ext/module/delegation'
|
17
|
-
# require 'active_support/core_ext/object/blank' # in object/misc.rb, string/misc.rb
|
18
|
-
# require 'active_support/core_ext/object/duplicable'
|
19
|
-
# require 'active_support/core_ext/string/starts_ends_with'
|
20
|
-
# require 'active_support/core_ext/string/strip'
|
21
|
-
# require 'active_support/core_ext/string/inflections' # in autoreq; module/misc.rb
|
22
|
-
# require 'active_support/core_ext/integer/multiple'
|
23
|
-
# require 'active_support/core_ext/integer/inflections'
|
24
|
-
# require 'active_support/core_ext/enumerable'
|
25
|
-
# require 'active_support/core_ext/array/extract_options'
|
26
|
-
# require 'active_support/core_ext/hash/conversions' # such as #to_xml
|
27
|
-
# require 'active_support/core_ext/hash/reverse_merge' # aliased in hash/misc.rb
|
28
|
-
# require 'active_support/core_ext/hash/deep_merge'
|
29
|
-
# require 'active_support/core_ext/hash/diff'
|
30
|
-
# require 'active_support/core_ext/hash/except'
|
31
|
-
# require 'active_support/core_ext/hash/keys'
|
32
|
-
# require 'active_support/core_ext/hash/slice'
|
33
|
-
# require 'active_support/core_ext/hash/indifferent_access'
|
5
|
+
require "y_support/version"
|
data/test/misc_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: y_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|