Module: NameMagic::ClassMethods

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

Overview

Class methods for the classes that include NameMagic.

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.)



51
52
53
# File 'lib/y_support/name_magic/class_methods.rb', line 51

def __avid_instances__
  namespace == self ? super : 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’s name for named instances, nil for anonymous instances, and false if there was no such registered instance. The optional second argument has the same meaning as in NameMaic::ClassMethods#instances.



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

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.)



43
44
45
# File 'lib/y_support/name_magic/class_methods.rb', line 43

def __instances__
  namespace == self ? super : namespace.__instances__
end

#avid(*ordered_args, **named_args, &block) ⇒ Object

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



195
196
197
# File 'lib/y_support/name_magic/class_methods.rb', line 195

def avid *ordered_args, **named_args, &block
  new *ordered_args, **named_args.update( name_avid: true ), &block
end

#const_magicObject

Searches all the modules in the the object space for constants pointing to anonymous instances of this class, and names them accordingly. The number of remaining anonymous instances is returned.



73
74
75
# File 'lib/y_support/name_magic/class_methods.rb', line 73

def const_magic
  namespace == self ? super : namespace.const_magic
end

#forget(instance, option = true) ⇒ Object

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



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

def forget instance, option=true
  namespace == self || ! option ? super : namespace.forget( instance instance )
end

#forget_all_instancesObject

Clears namespace-owned references to all the instances.



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

def forget_all_instances
  namespace == self ? super : namespace.forget_all_instances
end

#forget_nameless_instancesObject

Clears namespace-owned references to all the anonymous instances.



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

def forget_nameless_instances
  namespace == self ? super : namespace.forget_nameless_instances
end

#instance(instance, 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.



60
61
62
63
64
65
66
67
# File 'lib/y_support/name_magic/class_methods.rb', line 60

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

#instance_names(option = true) ⇒ Object

Deprecated method to get full names of the named instances. Use instances.names instead. Takes one optional argument, same as #instances method.



33
34
35
36
# File 'lib/y_support/name_magic/class_methods.rb', line 33

def instance_names option=true
  warn "Method #instance_names is deprecated. Use 'instances._names_' or 'instances.names' instead!"
  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 (ie. excluding the instances of the subclasses of this class). 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)



23
24
25
26
27
# File 'lib/y_support/name_magic/class_methods.rb', line 23

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.



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

def name_get_hook &block
  namespace == self ? super : 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
# File 'lib/y_support/name_magic/class_methods.rb', line 136

def name_set_hook &block
  namespace == self ? super : 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.



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

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

#namespace!Object

Sets the namespace for the class to self.



161
162
163
# File 'lib/y_support/name_magic/class_methods.rb', line 161

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

#namespace=(modul) ⇒ Object

Sets the namespace for the class.



153
154
155
156
157
# File 'lib/y_support/name_magic/class_methods.rb', line 153

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 by constant assignment, NameMagic redefines #new method so as to swallow name argument :name (alias :ɴ), and naming the constructed instance by it. Also, :name_avid option may be supplied, which, if true, makes the instance capable of avid naming: Overwriting (stealing) a name already given to another instance.



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

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 given, make the inst. avid unless expressly prohibited.
        __avid_instances__ << inst unless avid == false
      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.



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

def new_instance_hook &block
  namespace == self ? super : namespace.new_instance_hook( &block )
end

#validate_name(name) ⇒ Object

Performs general name validation.



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

def validate_name name
  namespace == self ? super : namespace.validate_name( name )
end