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.



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

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.



198
199
200
201
# File 'lib/y_support/name_magic/class_methods.rb', line 198

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
# File 'lib/y_support/name_magic/class_methods.rb', line 69

def const_magic
  return super if namespace == self
  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.)



87
88
89
90
91
# File 'lib/y_support/name_magic/class_methods.rb', line 87

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.



113
114
115
116
# File 'lib/y_support/name_magic/class_methods.rb', line 113

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.



106
107
108
109
# File 'lib/y_support/name_magic/class_methods.rb', line 106

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.



148
149
150
151
# File 'lib/y_support/name_magic/class_methods.rb', line 148

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.



136
137
138
139
# File 'lib/y_support/name_magic/class_methods.rb', line 136

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.



77
78
79
80
81
# File 'lib/y_support/name_magic/class_methods.rb', line 77

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.



163
164
165
# File 'lib/y_support/name_magic/class_methods.rb', line 163

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

#namespace=(modul) ⇒ Object

Sets the namespace of the class.



155
156
157
158
159
# File 'lib/y_support/name_magic/class_methods.rb', line 155

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.



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

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.



122
123
124
125
# File 'lib/y_support/name_magic/class_methods.rb', line 122

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