Module: NameMagic::ClassMethods
- Defined in:
- lib/y_support/name_magic/class_methods.rb
Overview
Class methods for the classes that include NameMagic.
Class Method Summary collapse
-
.delegate_to_namespace(*symbols) ⇒ Object
Delegates methods to the namespace used by the class.
Instance Method Summary collapse
-
#__forget__(instance) ⇒ Object
De-registers an instance without performing #const_magic first.
-
#forget(instance) ⇒ Object
Clears namespace-owned references to the specified instance.
-
#forget_all_instances ⇒ Object
Clears references to all the instances.
-
#instance(instance) ⇒ Object
Returns the instance identified by the first argument.
-
#instances ⇒ Object
Returns the registered instances.
-
#nameless_instances ⇒ Object
Returns those of the registered instances, which are nameless.
-
#namespace! ⇒ Object
Sets the namespace for the class to self.
-
#namespace=(modul) ⇒ Object
Sets the namespace for the class.
-
#new(*args, &block) ⇒ Object
In addition to the ability to name objects by constant assignment it provides,
NameMagic
modifies #new method so that it will swallow certain parameters, namely:name
(alias:ɴ
),:name!
and:avid
.
Class Method Details
.delegate_to_namespace(*symbols) ⇒ Object
Delegates methods to the namespace used by the class. Since the class frequently acts as its own namespace, this delegation requires special handling.
10 11 12 13 14 15 16 17 |
# File 'lib/y_support/name_magic/class_methods.rb', line 10 def self.delegate_to_namespace *symbols symbols.each { |ß| module_eval "def #{ß} *args\n" + " return super if namespace == self\n" + " namespace.#{ß}( *args )\n" + "end" } end |
Instance Method Details
#__forget__(instance) ⇒ Object
De-registers an instance without performing #const_magic first. The argument must be a registered instance, or TypeError ensues. Returns instance name for forgotten named instances, nil for forgotten nameless instances.
99 100 101 102 103 104 |
# File 'lib/y_support/name_magic/class_methods.rb', line 99 def __forget__ instance fail TypeError, "Supplied argument is not an instance " + "of #{self}!" unless instance.is_a? self return super if namespace == self namespace.__forget__ instance end |
#forget(instance) ⇒ Object
Clears namespace-owned references to the specified instance. (This is different from de-naming an instance by setting inst.name = nil
, which makes the instance anonymous, but still registered.)
89 90 91 92 |
# File 'lib/y_support/name_magic/class_methods.rb', line 89 def forget instance return super if namespace == self namespace.forget( instance instance ) end |
#forget_all_instances ⇒ Object
Clears references to all the instances.
108 109 110 111 |
# File 'lib/y_support/name_magic/class_methods.rb', line 108 def forget_all_instances return super if namespace == self instances.map { |instance| __forget__ instance } end |
#instance(instance) ⇒ Object
Returns the instance identified by the first argument.
67 68 69 70 71 72 73 |
# File 'lib/y_support/name_magic/class_methods.rb', line 67 def instance instance return super if namespace == self namespace.instance( instance ).tap do |i| fail NameError, "No #{self} instance #{instance} " + "registered in #{namespace}!" unless i.kind_of? self end end |
#instances ⇒ Object
Returns the registered instances. Example:
class Animal; include NameMagic end Cat, Dog = Class.new( Animal ), Class.new( Animal ) Spot, Livia = Dog.new, Cat.new Animal.instances #=> [Spot, Livia] Dog.instances #=> [Spot] Cat.instances #=> [Livia]
60 61 62 63 |
# File 'lib/y_support/name_magic/class_methods.rb', line 60 def instances return super if namespace == self namespace.instances.select { |i| i.kind_of? self } end |
#nameless_instances ⇒ Object
Returns those of the registered instances, which are nameless.
77 78 79 80 81 82 |
# File 'lib/y_support/name_magic/class_methods.rb', line 77 def nameless_instances return super if namespace == self __instances__ .select { |key, val| val.nil? and key.is_a? self } .keys end |
#namespace! ⇒ Object
Sets the namespace for the class to self.
45 46 47 |
# File 'lib/y_support/name_magic/class_methods.rb', line 45 def namespace! nil.tap { self.namespace = self } end |
#namespace=(modul) ⇒ Object
Sets the namespace for the class.
36 37 38 39 40 41 |
# File 'lib/y_support/name_magic/class_methods.rb', line 36 def namespace= modul fail "Namespace cannot be redefined when instance registry " + "is not empty!" unless instances.empty? modul.extend ::NameMagic::Namespace define_singleton_method :namespace do modul end end |
#new(*args, &block) ⇒ Object
In addition to the ability to name objects by constant assignment it provides, NameMagic
modifies #new method so that it will swallow certain parameters, namely :name
(alias :ɴ
), :name!
and :avid
. These can be used to name instances right off the bat with #new constructor:
Human = Class.new do include NameMagic end Human.new name: “Fred” Human.instances #=> [Fred]
Option :avid
(true or false), when set to true, makes the instance so eager to be named that it will overwrite (steal) names already given to other instances. This allows us to redefine names to which we have already assigned something else.
Finally, parameter :name!
acts as :name
with :avid
set to true:
instance_1 = Human.new name: “Joe” instance_1.name #=> :Joe Human.instance( :Joe ) == instance_1 #=> true instance_2 = Human.new name!: “Joe” instance_2.name #=> :Joe instance_1.name #=> nil Human.instance( :Joe ) == instance_1 #=> false Human.instance( :Joe ) == instance_2 #=> true
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/y_support/name_magic/class_methods.rb', line 141 def new *args, &block # Extract hash from args. oo = if args.last.is_a? Hash then args.pop else {} end # Swallow :name / :ɴ parameters. requested_name = oo.delete( :name ) || oo.delete( :ɴ ) # Swallow :name! parameter. if oo[ :name! ] then fail ArgumentError, "Parameters :name! and :name (:ɴ) " + "cannot be supplied both at once!" if requested_name requested_name = oo.delete( :name! ) exclamation_mark = true else exclamation_mark = false end # Prepare the arguments for instantiation. args << oo unless oo.empty? # Instantiate. instance = super *args, &block # Instantiation contract specifies that instances are created # unnamed. Thus, register the instance and set its name to nil. __instances__.update( instance => nil ) # Instantiation contract specifies that instances are created # avid. Thus, make the instance avid. instance.send :make_avid! # Now, we have prepared the new instance nameless and avid # exactly according to the instantiation contract. Depending on # the arguments supplied to this method, the instance may soon # lose its avid state and get a name, but now, before any of # that happens, is the time to honor .instantiation_exec hook. honor_instantiation_exec( instance ) # Return the instance if no name was requested for it. return instance unless requested_name # Now we know that a name was requested. The necessary action # depends on whether :name (:ɴ) or :name! parameter was used. # But already now, we know that the instance no longer needs # to be avid. instance.make_not_avid! # Depending on whether :name (:ɴ) or :name! was supplied... if exclamation_mark then # Name the instance aggresively. instance.name! requested_name else # Name the instance only if the name is not already in use. instance.name = requested_name end # Return the instance. return instance end |