y_support 2.0.43 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7f4a0b0a8c590f42dd23407f86cccce3ea0b95b
4
- data.tar.gz: 2cb43420440e01d7932a373aa197204f3b7115d3
3
+ metadata.gz: d09cacddac5d80bc24a3064513b05fe98bb55535
4
+ data.tar.gz: a17182ae74bb384a3c4d13abf7dc34c3a4bf5060
5
5
  SHA512:
6
- metadata.gz: 13398ec84e28cd5fdda66ccd6b040f403129a74ddc88cb3b91a264117e08a0469cba1e0006cc5d03c541e697fb17b60c41248fb711b26a9ab0a240a21c08467b
7
- data.tar.gz: 5e3031f03fd0de7d043ace4d4b7e5c7a1f1a04ae042f6869c14bfa1e67776035efe804dd9ade11c999f441bf10c2f1a6856ca8b610f44509d4fcc257c3238a98
6
+ metadata.gz: 148b04b34ba5dc66cb8d09543ae78c8558203fd8107844c0958a06e609c9dced068bbbce52052a1a66040dafa199e6a6d8f95269f6fb3fc8402a5151d4500dba
7
+ data.tar.gz: bb923dc9a8b48d19bd89705e104f63251078c5e78800bbaac7b58dc182b1000e6514d3241f57b077963038af8f1b0daae2f8fd5cc454dfd55e0839cbf308688e
@@ -4,30 +4,168 @@ module NameMagic::ClassMethods
4
4
  # Presents the instances registered by the namespace. Takes one optional
5
5
  # argument. If set to _false_, the method returns all the instances
6
6
  # registered by the namespace. If set to _true_ (default), only returns
7
- # those instances registered by the namespace, which are of the exact same
8
- # class as the method's receiver. Example:
9
- #
10
- # class Animal; include NameMagic end
11
- # Cat, Dog = Class.new( Animal ), Class.new( Animal )
12
- # Spot = Dog.new
13
- # Livia = Cat.new
14
- # Animal.instances #=> returns 2 instances
15
- # Dog.instances #=> returns 1 instance
16
- # Dog.instances( false ) #=> returns 2 instances of the namespace Animal
7
+ # those instances registered by the namespace, which are of exactly the same
8
+ # class as the receiver. Example:
9
+ #
10
+ # <code>
11
+ # class Animal; include NameMagic end
12
+ # Cat, Dog = Class.new( Animal ), Class.new( Animal )
13
+ # Spot = Dog.new
14
+ # Livia = Cat.new
15
+ # Animal.instances #=> returns 2 instances (2 animals)
16
+ # Dog.instances #=> returns 1 instance (only 1 is of Dog subclass)
17
+ # Dog.instances( false ) #=> 2 instances again (all the animals)
18
+ # </code>
17
19
  #
18
- def instances option=false
19
- const_magic
20
- return __instances__.keys if option
21
- __instances__.keys.select { |i| i.kind_of? self }
20
+ def instances option=true
21
+ return super if namespace == self
22
+ ii = namespace.instances
23
+ option ? ii.select { |i| i.kind_of? self } : ii
22
24
  end
23
25
 
24
26
  # Presents the instance names. Takes one optional argument, same as
25
- # #instances method. Unnamed instances are completely disregarded.
27
+ # +#instances+ method.
26
28
  #
27
- def instance_names option=false
29
+ def instance_names option=true
28
30
  instances( option ).names( false )
29
31
  end
30
32
 
33
+ # Presents namespace-owned +@instances+ hash. The hash consists of pairs
34
+ # <code>{ instance => instance_name }</code>. Unnamed instances have +nil+
35
+ # assigned to them as their name. (The method does not trigger
36
+ # +#const_magic+.)
37
+ #
38
+ def __instances__
39
+ return super if namespace == self
40
+ namespace.__instances__
41
+ end
42
+
43
+ # Presents namespace-owned +@avid_instances+ (array of avid instances). "Avid"
44
+ # means that the instance is able to overwrite a name used by another
45
+ # registered instance. (This method does not trigger +#const_magic+.)
46
+ #
47
+ def __avid_instances__
48
+ return super if namespace == self
49
+ namespace.__avid_instances__
50
+ end
51
+
52
+ # Returns the instance identified by the first argument, which can typically
53
+ # be a name (string/symbol). If a registered instance is supplied, it is
54
+ # returned without change. The second argument is optional, with the same
55
+ # meaning as in +NameMagic::ClassMethods#instances+ method.
56
+ #
57
+ def instance id, option=true
58
+ return super if namespace == self
59
+ namespace.instance( id ).tap { |inst|
60
+ fail NameError, "No #{self} instance #{id} registered in " +
61
+ "#{namespace}!" unless inst.kind_of? self if option
62
+ }
63
+ end
64
+
65
+ # Searches all the modules in the the object space for constants containing
66
+ # receiver class objects, and names the found instances accordingly. The
67
+ # number of the remaining nameless instances is returned.
68
+ #
69
+ def const_magic
70
+ puts "#{self}#const_magic invoked!" if ::NameMagic::DEBUG
71
+ return super if namespace == self
72
+ puts "self is not namespace, #const_magic delegated to #{namespace}" if ::NameMagic::DEBUG
73
+ namespace.const_magic
74
+ end
75
+
76
+ # Returns the nameless instances. The optional argument has the same meaning
77
+ # as in +NameMagic::ClassMethods#instances+ method.
78
+ #
79
+ def nameless_instances option=true
80
+ return super if namespace == self
81
+ ii = namespace.nameless_instances
82
+ option ? ii.select { |i| i.kind_of? self } : ii
83
+ end
84
+
85
+ # Clears namespace-owned references to a specified instance. (This is
86
+ # different from "unnaming" an instance by setting <code>inst.name =
87
+ # nil</code>, which makes the instance anonymous, but still registered.)
88
+ #
89
+ def forget instance_identifier, option=true
90
+ if namespace == self || ! option then super else
91
+ namespace.forget instance( instance_identifier )
92
+ end
93
+ end
94
+
95
+ # Clears namespace-owned references to an instance, without performing
96
+ # #const_magic first. The argument should be a registered instance. Returns
97
+ # the instance name, or _false_, if there was no such registered instance.
98
+ #
99
+ def __forget__( instance, option=true )
100
+ return super if namespace == self
101
+ fail NameError, "Supplied argument not an instance of #{self}!" unless
102
+ instance.is_a? self if option
103
+ namespace.__forget__ instance
104
+ end
105
+
106
+ # Clears namespace-owned references to all the anonymous instances.
107
+ #
108
+ def forget_nameless_instances
109
+ return super if namespace == self
110
+ namespace.forget_nameless_instances
111
+ end
112
+
113
+ # Clears namespace-owned references to all the instances.
114
+ #
115
+ def forget_all_instances
116
+ return super if namespace == self
117
+ namespace.forget_all_instances
118
+ end
119
+
120
+ # Registers a hook to execute upon instantiation. Expects a unary block, whose
121
+ # argument represents the new instance. It is called right after instantiation,
122
+ # but before naming the instance.
123
+ #
124
+ def new_instance_hook &block
125
+ return super if namespace == self
126
+ namespace.new_instance_hook &block
127
+ end
128
+
129
+ # Registers a hook to execute upon instance naming. Expects a ternary block,
130
+ # with arguments instance, name, old_name, representing respectively the
131
+ # instance to be named, the requested name, and the previous name of that
132
+ # instance (if any). The output of the block should be the name to actually
133
+ # be used. In other words, the hook can be used (among other things) to check
134
+ # and/or modify the requested name when christening the instance. It is the
135
+ # responsibility of this block to output a symbol that can be used as a Ruby
136
+ # constant name.
137
+ #
138
+ def name_set_hook &block
139
+ return super if namespace == self
140
+ namespace.name_set_hook &block
141
+ end
142
+
143
+ # Registers a hook to execute whenever the instance is asked its name. The
144
+ # instance names are objects that are kept in a hash referred to by
145
+ # +@instances+ variable owned by the namespace. Normally, +NameMagic#name+
146
+ # simply returns the name of the instance, as found in the +@instances+ hash.
147
+ # When +name_get_hook+ is defined, this name is transformed by it before being
148
+ # returned.
149
+ #
150
+ def name_get_hook &block
151
+ return super if namespace == self
152
+ namespace.name_get_hook &block
153
+ end
154
+
155
+ # Sets the namespace of the class.
156
+ #
157
+ def namespace= modul
158
+ puts "Assigning #{modul} as the namespace of #{self}." if ::NameMagic::DEBUG
159
+ modul.extend ::NameMagic::NamespaceMethods
160
+ define_singleton_method :namespace do modul end
161
+ end
162
+
163
+ # Sets the namespace for the class to self.
164
+ #
165
+ def namespace!
166
+ nil.tap { self.namespace = self }
167
+ end
168
+
31
169
  # In addition the ability to name objects upon constant assignment, as common
32
170
  # with eg. Class instances, NameMagic redefines class method #new so that it
33
171
  # swallows the named argument :name (alias :ɴ), and takes care of naming the
@@ -36,23 +174,21 @@ module NameMagic::ClassMethods
36
174
  # another object) if set to _true_.
37
175
  #
38
176
  def new *args, &block
39
- oo = args[-1].is_a?( Hash ) ? args.pop : {} # extract hash
40
- nm = if oo[:name] then oo.delete :name # consume :name if supplied
41
- elsif oo[:ɴ] then oo.delete :ɴ # consume :ɴ if supplied
42
- else nil end
43
- avid = oo[:name_avid] ? oo.delete( :name_avid ) : false # => true/false
177
+ oo = if args[-1].is_a? Hash then args.pop else {} end # extract hash
178
+ nm = oo.delete( :name ) || oo.delete( :ɴ ) # consume :name / :ɴ if given
179
+ avid = !!oo.delete( :name_avid )
44
180
  # Avoid overwriting existing names unless avid:
45
181
  fail NameError, "#{self} instance #{nm} already exists!" if
46
182
  __instances__.keys.include? nm unless avid
47
183
  args << oo unless oo.empty? # prepare the arguments
48
- new_before_name_magic( *args, &block ).tap do |new_inst| # instantiate
49
- __instances__.update new_inst => nil # Instance is created unnamed...
50
- namespace.new_instance_closure.tap { |λ|
51
- λ.( new_inst ) if λ
52
- if nm then # name has been supplied, we can name the instance:
53
- avid ? new_inst.name!( nm ) : new_inst.name = nm
54
- else # name hasn't been supplied, making the instance avid:
55
- __avid_instances__ << new_inst
184
+ super( *args, &block ).tap do |inst| # instantiate
185
+ __instances__.update( inst => nil ) # Instances are created unnamed...
186
+ namespace.new_instance_hook.tap { |λ|
187
+ λ.( inst ) if λ
188
+ if nm then # Name supplied, name the instance.
189
+ avid ? inst.name!( nm ) : inst.name = nm
190
+ else # Name not supplied, make the instance avid.
191
+ __avid_instances__ << inst
56
192
  end
57
193
  }
58
194
  end
@@ -65,4 +201,20 @@ module NameMagic::ClassMethods
65
201
  oo = args[-1].is_a?( Hash ) ? args.pop : {} # extract options
66
202
  new *args, oo.update( name_avid: true ), &block
67
203
  end
204
+
205
+ private
206
+
207
+ # Checks all the constants in some module's namespace, recursively.
208
+ #
209
+ def serve_all_modules
210
+ return super if namespace == self
211
+ namespace.serve_all_modules
212
+ end
213
+
214
+ # Performs general name validation.
215
+ #
216
+ def validate_name name
217
+ return super if namespace == self
218
+ namespace.validate_name name
219
+ end
68
220
  end # module NameMagic::ClassMethods
@@ -1,4 +1,4 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
2
 
3
3
  class Hash
4
4
  # Maps a hash into a hash, whose keys have been replaced with names of the
@@ -1,76 +1,52 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
2
 
3
3
  module NameMagic
4
4
  module NamespaceMethods
5
- # Presents class-owned namespace. By default, this is the class itself, but
6
- # may be overriden to use some other module as a namespace.
7
- #
8
- def namespace
9
- self
10
- end
11
-
12
- # Sets the namespace of the class.
13
- #
14
- def namespace= modul
15
- modul.extend ::NameMagic::NamespaceMethods unless modul == self
16
- tap { define_singleton_method :namespace do modul end }
17
- end
18
-
19
- # Makes the class/module its own namespace. This is useful especially to tell
20
- # the subclasses of a class using NameMagic to maintain their own namespaces.
21
- #
22
- def namespace!
23
- nil.tap { self.namespace = self }
24
- end
25
-
26
- # Presents the instances registered by the namespace.
5
+ # Presents the instances registered in this namespace.
27
6
  #
28
- def instances
7
+ def instances *args
29
8
  const_magic
30
9
  __instances__.keys
31
10
  end
32
11
 
33
- # Presents the instance names. Takes one optional argument, same as
34
- # #instances method. Unnamed instances are completely disregarded.
12
+ # Presents the instance names registered in this namespace.
35
13
  #
36
- def instance_names
14
+ def instance_names *args
37
15
  instances.names( false )
38
16
  end
39
17
 
40
- # Presents namespace-owned @instances hash of pairs <code>{ instance =>
41
- # instance_name }</code>. Unnamed instances have nil value. (Also, this
42
- # method does not trigger #const_magic.)
18
+ # Presents namespace-owned +@instances+ hash. The hash consists of pairs
19
+ # <code>{ instance => instance_name }</code>. Unnamed instances have +nil+
20
+ # assigned to them as their name. (The method does not trigger
21
+ # +#const_magic+.)
43
22
  #
44
- def __instances__
45
- namespace.instance_variable_get( :@instances ) ||
46
- namespace.instance_variable_set( :@instances, {} )
23
+ def __instances__ *args
24
+ @instances ||= {}
47
25
  end
48
26
 
49
- # Presents namespace-owned @avid_instances array of avid instances. "Avid"
50
- # means that the instance is able to overwrite a name used by another
51
- # registered instance. (Also, this method does not trigger const_magic).
27
+ # Avid instances registered in this namespace. ("Avid" means that the
28
+ # instance is able to steal (overwrite) a name from another registered
29
+ # instance. (The method does not trigger +#const_magic+.)
52
30
  #
53
- def __avid_instances__
54
- namespace.instance_variable_get( :@avid_instances ) ||
55
- namespace.instance_variable_set( :@avid_instances, [] )
31
+ def __avid_instances__ *args
32
+ @avid_instances ||= []
56
33
  end
57
34
 
58
- # Returns the instance identified by the argument. NameError is raised, if
59
- # the argument does not identify an instance. (It can be an instance name
60
- # (string/symbol), or an instance itself, in which case, it is just returned
61
- # back without changes.)
35
+ # Returns the instance identified by the argument, which can be typically
36
+ # a name (string/symbol). If a registered instance is supplied, it will be
37
+ # returned unchanged.
62
38
  #
63
- def instance identifier
64
- puts "#instance( #{identifier} )" if DEBUG
39
+ def instance id, *args
40
+ # puts "#instance( #{identifier} )" if DEBUG
65
41
  # In @instances hash, value 'nil' indicates a nameless instance!
66
- fail TypeError, "'nil' is not an instance identifier!" if identifier.nil?
42
+ fail TypeError, "'nil' is not an instance identifier!" if id.nil?
67
43
  ii = instances
68
- return identifier if ii.include? identifier # return the instance back
44
+ return id if ii.include? id # return the instance back
69
45
  begin # identifier not a registered instace -- treat it as a name
70
- ary = [identifier, identifier.to_sym]
71
- ii.find do |i| ary.include? i.name end
46
+ ary = [id, id.to_sym]
47
+ ii.find { |inst| ary.include? inst.name }
72
48
  rescue NoMethodError
73
- end or raise NameError, "No instance #{identifier} in #{self}."
49
+ end or fail NameError, "No instance #{id} in #{self}."
74
50
  end
75
51
 
76
52
  # Searches all the modules in the the object space for constants containing
@@ -78,24 +54,23 @@ module NameMagic
78
54
  # number of the remaining nameless instances is returned.
79
55
  #
80
56
  def const_magic
57
+ puts "#{self}#const_magic invoked!" if ::NameMagic::DEBUG
81
58
  return 0 if nameless_instances.size == 0
82
59
  serve_all_modules
83
60
  return nameless_instances.size
84
- end # def const_magic
85
-
61
+ end
62
+
86
63
  # Returns those instances, which are nameless (whose name is set to nil).
87
64
  #
88
- def nameless_instances
65
+ def nameless_instances *args
89
66
  __instances__.select { |key, val| val.nil? }.keys
90
67
  end
91
- alias unnamed_instances nameless_instances
92
- alias anonymous_instances nameless_instances
93
68
 
94
69
  # Clears namespace-owned references to a specified instance. (This is
95
70
  # different from "unnaming" an instance by setting <code>inst.name =
96
71
  # nil</code>, which makes the instance anonymous, but still registered.)
97
72
  #
98
- def forget( instance_identifier )
73
+ def forget instance_identifier, *args
99
74
  inst = begin
100
75
  instance( instance_identifier )
101
76
  rescue ArgumentError
@@ -112,7 +87,7 @@ module NameMagic
112
87
  # #const_magic first. The argument should be a registered instance. Returns
113
88
  # the instance name, or _false_, if there was no such registered instance.
114
89
  #
115
- def __forget__( instance )
90
+ def __forget__( instance, *args )
116
91
  return false unless __instances__.keys.include? instance
117
92
  namespace.send :remove_const, instance.name if instance.name
118
93
  __avid_instances__.delete( instance )
@@ -127,8 +102,6 @@ module NameMagic
127
102
  __avid_instances__.delete inst # also from here
128
103
  }
129
104
  end
130
- alias forget_unnamed_instances forget_nameless_instances
131
- alias forget_anonymous_instances forget_nameless_instances
132
105
 
133
106
  # Clears namespace-owned references to all the instances.
134
107
  #
@@ -139,48 +112,50 @@ module NameMagic
139
112
  }
140
113
  end
141
114
 
142
- # Registers a hook to execute whenever name magic creates a new instance of
143
- # the class including NameMagic. The block should take one argument (the new
144
- # instance that was created) and is called in #new method right after
145
- # instantiation, but before naming.
115
+ # Registers a hook to execute upon instantiation. Expects a unary block, whose
116
+ # argument represents the new instance. It is called right after instantiation,
117
+ # but before naming the instance.
146
118
  #
147
- def new_instance_closure &block
148
- namespace.new_instance_closure &block unless namespace == self
149
- @new_instance_closure = block if block
150
- @new_instance_closure ||= -> instance { instance }
151
- end
152
- alias new_instance_hook new_instance_closure
153
-
154
- # Registers a hook to execute whenever name setting is performed on an
155
- # instance. The block should take three arguments (instance, name, old_name).
156
- # The output value of the block is the name to be actually used the hook
157
- # thus allows to define transformations on the name when naming. It is the
158
- # responsibility of the block to output a suitable symbol (capitalized,
159
- # usable as a constant name etc.)
119
+ def new_instance_hook &block
120
+ @new_instance_hook = block if block
121
+ @new_instance_hook ||= -> instance { instance }
122
+ end
123
+
124
+ # Registers a hook to execute upon instance naming. Expects a ternary block,
125
+ # with arguments instance, name, old_name, representing respectively the
126
+ # instance to be named, the requested name, and the previous name of that
127
+ # instance (if any). The output of the block should be the name to actually
128
+ # be used. In other words, the hook can be used (among other things) to check
129
+ # and/or modify the requested name when christening the instance. It is the
130
+ # responsibility of this block to output a symbol that can be used as a Ruby
131
+ # constant name.
160
132
  #
161
- def name_set_closure &block
162
- namespace.name_set_closure &block unless namespace == self
163
- @name_set_closure = block if block
164
- @name_set_closure ||= -> name, instance, old_name=nil { name }
133
+ def name_set_hook &block
134
+ @name_set_hook = block if block
135
+ @name_set_hook ||= -> name, instance, old_name=nil { name }
165
136
  end
166
- alias name_set_hook name_set_closure
167
137
 
168
- # Registers a hook to execute whenever the instance is asked about its
169
- # name. The name object contained in __instances__[self] is subjected
170
- # to the name_get_closure before being returned as instance name.
138
+ # Registers a hook to execute whenever the instance is asked its name. The
139
+ # instance names are objects that are kept in a hash referred to by
140
+ # +@instances+ variable owned by the namespace. Normally, +NameMagic#name+
141
+ # simply returns the name of the instance, as found in the +@instances+ hash.
142
+ # When +name_get_hook+ is defined, this name is transformed by it before being
143
+ # returned.
171
144
  #
172
- def name_get_closure &block
173
- namespace.name_get_closure &block unless namespace == self
174
- @name_get_closure = block if block
175
- @name_get_closure ||= -> name { name }
145
+ def name_get_hook &block
146
+ @name_get_hook = block if block
147
+ @name_get_hook ||= -> name { name }
176
148
  end
177
- alias name_get_hook name_get_closure
178
149
 
179
150
  private
180
151
 
181
152
  # Checks all the constants in some module's namespace, recursively.
182
153
  #
183
154
  def serve_all_modules
155
+ if DEBUG then
156
+ puts "#{self}#serve_all_modules invoked!"
157
+ if name.nil? then puts "(ancestors: #{ancestors.take( 4 ).join ', '}" end
158
+ end
184
159
  todo = ( nameless_instances + __avid_instances__ ).map( &:object_id ).uniq
185
160
  ObjectSpace.each_object Module do |ɱ|
186
161
  ɱ.constants( false ).each do |const_ß|
@@ -189,21 +164,19 @@ module NameMagic
189
164
  rescue LoadError, StandardError; next end
190
165
  next unless todo.include? ◉.object_id
191
166
  puts "NameMagic: Anonymous object under #{const_ß}!" if DEBUG
192
- if __avid_instances__.map( &:object_id ).include? ◉.object_id # avid
193
- puts "NameMagic: It is avid." if DEBUG
194
- __avid_instances__ # 1. remove from avid list
195
- .delete_if { |inst| inst.object_id == ◉.object_id }
196
- ◉.name! const_ß # 2. name rudely
197
- else puts "NameMagic: It is not avid." if DEBUG # not avid
198
- ɴ = validate_name( name_set_closure.( const_ß, ◉, nil ) ).to_sym
167
+ if ◉.avid? then puts "NameMagic: It is avid." if DEBUG
168
+ ◉.make_not_avid! # 1. Remove it from the list of avid instances.
169
+ ◉.name! const_ß # 2. Name it rudely.
170
+ else puts "NameMagic: It is not avid." if DEBUG
171
+ ɴ = validate_name( name_set_hook.( const_ß, ◉, nil ) ).to_sym
199
172
  puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG
200
- conflicter = begin; namespace.const_get( ɴ ); rescue NameError; end
173
+ conflicter = begin; const_get( ɴ ); rescue NameError; end
201
174
  if conflicter then
202
175
  msg = "Another #{self}-registered instance named '#{ɴ}' exists!"
203
176
  fail NameError, msg unless conflicter == ◉
204
177
  else # add the instance to the namespace
205
178
  __instances__.update( ◉ => ɴ )
206
- namespace.const_set( ɴ, ◉ )
179
+ const_set( ɴ, ◉ )
207
180
  end
208
181
  end
209
182
  todo.delete ◉.object_id # remove the id from todo list
@@ -71,25 +71,22 @@ require_relative 'name_magic/class_methods'
71
71
  module NameMagic
72
72
  DEBUG = false
73
73
 
74
- def self.included modul
75
- if modul.is_a? Class then # decorate #new
76
- class << modul
77
- alias :new_before_name_magic :new
78
- end
79
- modul.extend NameMagic::NamespaceMethods
80
- modul.extend NameMagic::ClassMethods
81
- # Attach namespace methods also to the namespace, if given
82
- begin
83
- if modul.namespace == modul then
84
- modul.define_singleton_method :namespace do modul end
85
- else
86
- modul.namespace.extend NameMagic::NamespaceMethods
74
+ def self.included target
75
+ if target.is_a? Class then # decorate #new
76
+ class << target
77
+ # Primer that sets the namespace of the class to self if the user has
78
+ # not defined otherwise when this method is first called.
79
+ #
80
+ def namespace
81
+ extend ::NameMagic::NamespaceMethods
82
+ define_singleton_method :namespace do self end # redefines itself
83
+ namespace
87
84
  end
88
- rescue NoMethodError
89
85
  end
86
+ target.singleton_class.class_exec { prepend NameMagic::ClassMethods }
90
87
  else # it is a Module -- infect it with this #include
91
- orig, this = modul.method( :included ), method( :included )
92
- modul.define_singleton_method :included do |m| this.( m ); orig.( m ) end
88
+ orig, this = target.method( :included ), method( :included )
89
+ target.define_singleton_method :included do |m| this.( m ); orig.( m ) end
93
90
  end
94
91
  end # self.included
95
92
 
@@ -111,24 +108,24 @@ module NameMagic
111
108
  #
112
109
  def __name__
113
110
  ɴ = self.class.__instances__[ self ]
114
- namespace.name_get_closure.( ɴ ) if ɴ
111
+ namespace.name_get_hook.( ɴ ) if ɴ
115
112
  end
116
113
 
117
114
  # Names an instance, cautiously (ie. no overwriting of existing names).
118
115
  #
119
116
  def name=( ɴ )
120
117
  old_ɴ = namespace.__instances__[ self ] # previous name
121
- if ɴ then puts "NameMagic: Naming with argument #{ɴ}." if DEBUG
122
- ɴ = namespace.send( :validate_name, # honor the hook
123
- namespace.name_set_closure.( ɴ, self, old_ɴ ) ).to_sym
124
- puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG
118
+ if ɴ then # puts "NameMagic: Naming with argument #{ɴ}." if DEBUG
119
+ ɴ = namespace.send( :validate_name, # honor the hook
120
+ namespace.name_set_hook.( ɴ, self, old_ɴ ) ).to_sym
121
+ # puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG
125
122
  return if old_ɴ == ɴ # already named as required
126
123
  fail NameError, "Name '#{ɴ}' already exists in #{namespace} namespace!" if
127
124
  self.class.__instances__.rassoc( ɴ )
128
125
  namespace.const_set ɴ, self # write a constant
129
126
  namespace.__instances__[ self ] = ɴ # write to @instances
130
127
  namespace.__forget__ old_ɴ # forget the old name of self
131
- else puts "NameMagic: Unnaming #{old_ɴ || self}" if DEBUG
128
+ else # puts "NameMagic: Unnaming #{old_ɴ || self}" if DEBUG
132
129
  namespace.__instances__.update( self => nil ) # unname in @instances
133
130
  namespace.send :remove_const, old_ɴ if old_ɴ # remove namespace const.
134
131
  end
@@ -138,10 +135,10 @@ module NameMagic
138
135
  #
139
136
  def name!( ɴ )
140
137
  old_ɴ = namespace.__instances__[ self ] # previous name
141
- if ɴ then puts "NameMagic: Rudely naming with #{ɴ}." if DEBUG
138
+ if ɴ then # puts "NameMagic: Rudely naming with #{ɴ}." if DEBUG
142
139
  ɴ = namespace.send( :validate_name, # honor the hook
143
- namespace.name_set_closure.( ɴ, self, old_ɴ ) ).to_sym
144
- puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG
140
+ namespace.name_set_hook.( ɴ, self, old_ɴ ) ).to_sym
141
+ # puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG
145
142
  return false if old_ɴ == ɴ # already named as required
146
143
  pair = namespace.__instances__.rassoc( ɴ )
147
144
  namespace.__forget__( pair[0] ) if pair # rudely forget the collider
@@ -152,4 +149,16 @@ module NameMagic
152
149
  self.name = nil # unnaming, no collider issues
153
150
  end
154
151
  end
152
+
153
+ # Is the instance avid for a name? (Will it overwrite other instance names?)
154
+ #
155
+ def avid?
156
+ namespace.__avid_instances__.any? &method( :equal? )
157
+ end
158
+
159
+ # Make the instance not avid.
160
+ #
161
+ def make_not_avid!
162
+ namespace.__avid_instances__.delete_if { |i| i.object_id == object_id }
163
+ end
155
164
  end # module NameMagic
@@ -1,4 +1,4 @@
1
1
  module YSupport
2
- VERSION = "2.0.43"
2
+ VERSION = "2.1.0"
3
3
  DEBUG = false
4
4
  end
@@ -11,18 +11,20 @@ describe NameMagic do
11
11
  @reporter = Object.new
12
12
  puts "..."
13
13
  @reporter.singleton_class.class_exec { attr_reader :report, :naming }
14
- @ç.namespace.new_instance_closure do |instance|
14
+ @ç.ancestors.must_include NameMagic
15
+ @ç.singleton_class.ancestors.must_include NameMagic::ClassMethods
16
+ @ç.namespace.new_instance_hook do |instance|
15
17
  @reporter.define_singleton_method :report do "Instance reported" end
16
18
  end
17
- @ç.namespace.name_set_closure do |name, instance, old_name|
19
+ @ç.namespace.name_set_hook do |name, instance, old_name|
18
20
  @reporter.define_singleton_method :name_set do
19
21
  "Name of the new instance was #{name}"
20
22
  end
21
23
  name
22
24
  end
23
- @ç.name_get_closure do |name_object|
25
+ @ç.name_get_hook do |name_object|
24
26
  @reporter.define_singleton_method :name_get do
25
- "Name get closure called on #{name_object}"
27
+ "Name get hook called on #{name_object}"
26
28
  end
27
29
  name_object
28
30
  end
@@ -37,7 +39,7 @@ describe NameMagic do
37
39
  @reporter.report.must_equal "Instance reported"
38
40
  @reporter.name_set.must_equal "Name of the new instance was Boris"
39
41
  x.name.must_equal :Boris
40
- @reporter.name_get.must_equal "Name get closure called on Boris"
42
+ @reporter.name_get.must_equal "Name get hook called on Boris"
41
43
  ufo = @ç.new
42
44
  @ç.nameless_instances.must_equal [ufo]
43
45
  UFO = @ç.new
@@ -45,17 +47,21 @@ describe NameMagic do
45
47
  @reporter.name_set.must_equal "Name of the new instance was Boris"
46
48
  UFO.name
47
49
  @reporter.name_set.must_equal "Name of the new instance was UFO"
48
- @reporter.name_get.must_equal "Name get closure called on UFO"
50
+ @reporter.name_get.must_equal "Name get hook called on UFO"
49
51
  Elaine = @ç.new
50
52
  Elaine.name.must_equal :Elaine
51
53
  m = Module.new
52
54
  XXX = m
53
55
  @ç.namespace = XXX
54
56
  @ç.namespace.must_equal m
57
+ @ç.singleton_class.must_include ::NameMagic::ClassMethods
58
+ m.singleton_class.must_include ::NameMagic::NamespaceMethods
55
59
  Rover = @ç.new
60
+ @ç.namespace.must_equal XXX
61
+ @ç.nameless_instances.must_equal [ Rover ]
56
62
  @ç.const_magic
57
- XXX::Rover.must_be_kind_of @ç
58
63
  Rover.name.must_equal :Rover
64
+ XXX::Rover.must_be_kind_of @ç
59
65
  @ç.namespace!
60
66
  Spot = @ç.new
61
67
  @ç.const_magic
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: 2.0.43
4
+ version: 2.1.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-08-21 00:00:00.000000000 Z
11
+ date: 2013-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport