Module: NameMagic::ClassMethods

Defined in:
lib/y_support/name_magic/class_methods.rb

Instance Method Summary collapse

Instance Method Details

#__avid_instances__Object

Presents namespace-owned @avid_instances (array of avid instances). “Avid” means that the instance is able to overwrite a name used by another registered instance. (This method does not trigger #const_magic.)



47
48
49
50
# File 'lib/y_support/name_magic/class_methods.rb', line 47

def __avid_instances__
  return super if namespace == self
  namespace.__avid_instances__
end

#__forget__(instance, option = true) ⇒ Object

Clears namespace-owned references to an instance, without performing #const_magic first. The argument should be a registered instance. Returns the instance name, or false, if there was no such registered instance.



99
100
101
102
103
104
# File 'lib/y_support/name_magic/class_methods.rb', line 99

def __forget__( instance, option=true )
  return super if namespace == self
  fail NameError, "Supplied argument not an instance of #{self}!" unless
    instance.is_a? self if option
  namespace.__forget__ instance
end

#__instances__Object

Presents namespace-owned @instances hash. The hash consists of pairs { instance => instance_name }. Unnamed instances have nil assigned to them as their name. (The method does not trigger #const_magic.)



38
39
40
41
# File 'lib/y_support/name_magic/class_methods.rb', line 38

def __instances__
  return super if namespace == self
  namespace.__instances__
end

#avid(*args, &block) ⇒ Object

Calls #new in avid mode (name_avid: true); see #new method for avid mode explanation.



200
201
202
203
# File 'lib/y_support/name_magic/class_methods.rb', line 200

def avid *args, &block
  oo = args[-1].is_a?( Hash ) ? args.pop : {} # extract options
  new *args, oo.update( name_avid: true ), &block
end

#const_magicObject

Searches all the modules in the the object space for constants containing receiver class objects, and names the found instances accordingly. The number of the remaining nameless instances is returned.



69
70
71
72
73
74
# File 'lib/y_support/name_magic/class_methods.rb', line 69

def const_magic
  puts "#{self}#const_magic invoked!" if ::NameMagic::DEBUG
  return super if namespace == self
  puts "self is not namespace, #const_magic delegated to #{namespace}" if ::NameMagic::DEBUG
  namespace.const_magic
end

#forget(instance_identifier, option = true) ⇒ Object

Clears namespace-owned references to a specified instance. (This is different from “unnaming” an instance by setting inst.name = nil, which makes the instance anonymous, but still registered.)



89
90
91
92
93
# File 'lib/y_support/name_magic/class_methods.rb', line 89

def forget instance_identifier, option=true
  if namespace == self || ! option then super else
    namespace.forget instance( instance_identifier )
  end
end

#forget_all_instancesObject

Clears namespace-owned references to all the instances.



115
116
117
118
# File 'lib/y_support/name_magic/class_methods.rb', line 115

def forget_all_instances
  return super if namespace == self
  namespace.forget_all_instances
end

#forget_nameless_instancesObject

Clears namespace-owned references to all the anonymous instances.



108
109
110
111
# File 'lib/y_support/name_magic/class_methods.rb', line 108

def forget_nameless_instances
  return super if namespace == self
  namespace.forget_nameless_instances
end

#instance(id, option = true) ⇒ Object

Returns the instance identified by the first argument, which can typically be a name (string/symbol). If a registered instance is supplied, it is returned without change. The second argument is optional, with the same meaning as in NameMagic::ClassMethods#instances method.



57
58
59
60
61
62
63
# File 'lib/y_support/name_magic/class_methods.rb', line 57

def instance id, option=true
  return super if namespace == self
  namespace.instance( id ).tap { |inst|
    fail NameError, "No #{self} instance #{id} registered in " +
      "#{namespace}!" unless inst.kind_of? self if option
  }
end

#instance_names(option = true) ⇒ Object

Presents the instance names. Takes one optional argument, same as #instances method.



29
30
31
# File 'lib/y_support/name_magic/class_methods.rb', line 29

def instance_names option=true
  instances( option ).names( false )
end

#instances(option = true) ⇒ Object

Presents the instances registered by the namespace. Takes one optional argument. If set to false, the method returns all the instances registered by the namespace. If set to true (default), only returns those instances registered by the namespace, which are of exactly the same class as the receiver. Example:

class Animal; include NameMagic end Cat, Dog = Class.new( Animal ), Class.new( Animal ) Spot = Dog.new Livia = Cat.new Animal.instances #=> returns 2 instances (2 animals) Dog.instances #=> returns 1 instance (only 1 is of Dog subclass) Dog.instances( false ) #=> 2 instances again (all the animals)



20
21
22
23
24
# File 'lib/y_support/name_magic/class_methods.rb', line 20

def instances option=true
  return super if namespace == self
  ii = namespace.instances
  option ? ii.select { |i| i.kind_of? self } : ii
end

#name_get_hook(&block) ⇒ Object

Registers a hook to execute whenever the instance is asked its name. The instance names are objects that are kept in a hash referred to by @instances variable owned by the namespace. Normally, NameMagic#name simply returns the name of the instance, as found in the @instances hash. When name_get_hook is defined, this name is transformed by it before being returned.



150
151
152
153
# File 'lib/y_support/name_magic/class_methods.rb', line 150

def name_get_hook &block
  return super if namespace == self
  namespace.name_get_hook &block
end

#name_set_hook(&block) ⇒ Object

Registers a hook to execute upon instance naming. Expects a ternary block, with arguments instance, name, old_name, representing respectively the instance to be named, the requested name, and the previous name of that instance (if any). The output of the block should be the name to actually be used. In other words, the hook can be used (among other things) to check and/or modify the requested name when christening the instance. It is the responsibility of this block to output a symbol that can be used as a Ruby constant name.



138
139
140
141
# File 'lib/y_support/name_magic/class_methods.rb', line 138

def name_set_hook &block
  return super if namespace == self
  namespace.name_set_hook &block
end

#nameless_instances(option = true) ⇒ Object

Returns the nameless instances. The optional argument has the same meaning as in NameMagic::ClassMethods#instances method.



79
80
81
82
83
# File 'lib/y_support/name_magic/class_methods.rb', line 79

def nameless_instances option=true
  return super if namespace == self
  ii = namespace.nameless_instances
  option ? ii.select { |i| i.kind_of? self } : ii
end

#namespace!Object

Sets the namespace for the class to self.



165
166
167
# File 'lib/y_support/name_magic/class_methods.rb', line 165

def namespace!
  nil.tap { self.namespace = self }
end

#namespace=(modul) ⇒ Object

Sets the namespace of the class.



157
158
159
160
161
# File 'lib/y_support/name_magic/class_methods.rb', line 157

def namespace= modul
  puts "Assigning #{modul} as the namespace of #{self}." if ::NameMagic::DEBUG 
  modul.extend ::NameMagic::NamespaceMethods
  define_singleton_method :namespace do modul end
end

#new(*args, &block) ⇒ Object

In addition the ability to name objects upon constant assignment, as common with eg. Class instances, NameMagic redefines class method #new so that it swallows the named argument :name (alias :ɴ), and takes care of naming the instance accordingly. Also, :name_avid named argument mey be supplied, which makes the naming avid (able to overwrite the name already in use by another object) if set to true.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/y_support/name_magic/class_methods.rb', line 176

def new *args, &block
  oo = if args[-1].is_a? Hash then args.pop else {} end  # extract hash
  nm = oo.delete( :name ) || oo.delete(  )   # consume :name / :ɴ if given
  avid = !!oo.delete( :name_avid )
  # Avoid overwriting existing names unless avid:
  fail NameError, "#{self} instance #{nm} already exists!" if
    __instances__.keys.include? nm unless avid
  args << oo unless oo.empty?    # prepare the arguments
  super( *args, &block ).tap do |inst| # instantiate
    __instances__.update( inst => nil ) # Instances are created unnamed...
    namespace.new_instance_hook.tap { |λ|
      λ.( inst ) if λ
      if nm then # Name supplied, name the instance.
        avid ? inst.name!( nm ) : inst.name = nm
      else # Name not supplied, make the instance avid.
        __avid_instances__ << inst
      end
    }
  end
end

#new_instance_hook(&block) ⇒ Object

Registers a hook to execute upon instantiation. Expects a unary block, whose argument represents the new instance. It is called right after instantiation, but before naming the instance.



124
125
126
127
# File 'lib/y_support/name_magic/class_methods.rb', line 124

def new_instance_hook &block
  return super if namespace == self
  namespace.new_instance_hook &block
end