Module: NameMagic
- Defined in:
- lib/y_support/name_magic.rb
Overview
This mixin imitates Ruby constant magic and automates the named argument :name (alias :ɴ). One thus can write:
class Someclass; include NameMagic end
SomeName = SomeClass.new
and the resulting object will know its #name:
SomeName.name = "SomeName"
This is done by searching the whole Ruby namespace for constants, to which the object might have been assigned. The search is performed by the method #const_magic defined by this mixin. Once the object is found to be assigned to a constant, and named accordingly, its subsequent assignments to other constants have no additional effect.
Alternative way to create a named object is by specifying :name (alias :ɴ) named argument:
SomeClass.new a, b, ..., name: "SomeName", aa: v1, bb: v2 ...
Lastly, a name can be assigned by #name= accssor, as in
o = SomeClass.new
o.name = "SomeName"
Hook is provided for when the name magic is performed, as well as when the name is retrieved.
Defined Under Namespace
Modules: ClassMethods, NamespaceMethods
Constant Summary collapse
- DEBUG =
false
Class Method Summary collapse
Instance Method Summary collapse
-
#name ⇒ Object
(also: #ɴ)
Retrieves an instance name (demodulized).
-
#name!(ɴ) ⇒ Object
Names an instance, aggresively (overwrites existing names).
-
#name=(ɴ) ⇒ Object
Names an instance, cautiously (ie. no overwriting of existing names).
-
#name_or_object_id ⇒ Object
(also: #ɴ_)
Retrieves either an instance name (if present), or an object id.
Class Method Details
.included(ɱ) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/y_support/name_magic.rb', line 36 def self.included ɱ case ɱ when Class then # we will decorate its #new method class << ɱ alias :original_method_new :new # Make space to decorate #new end # Attach the decorators etc. ɱ.extend ::NameMagic::ClassMethods ɱ.extend ::NameMagic::NamespaceMethods # Attach namespace methods also to the namespace, if given. begin if ɱ.namespace == ɱ then ɱ.define_singleton_method :namespace do ɱ end else ɱ.namespace.extend ::NameMagic::NamespaceMethods end rescue NoMethodError end else # it is a Module; we'll infect it with our #included method ɱ_included, this_included = ɱ.method( :included ), method( :included ) ɱ.define_singleton_method :included do |ç| this_included.( ç ) ɱ_included.( ç ) end end end |
Instance Method Details
#name ⇒ Object Also known as: ɴ
Retrieves an instance name (demodulized).
65 66 67 68 69 70 71 72 |
# File 'lib/y_support/name_magic.rb', line 65 def name self.class.const_magic ɴ = self.class.__instances__[ self ] if ɴ then name_get_closure = self.class.instance_variable_get :@name_get_closure name_get_closure ? name_get_closure.( ɴ ) : ɴ else nil end end |
#name!(ɴ) ⇒ Object
Names an instance, aggresively (overwrites existing names).
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/y_support/name_magic.rb', line 105 def name!( ɴ ) puts "NameMagic: Rudely naming with argument #{ɴ}." if DEBUG old_ɴ = self.class.__instances__[ self ] # get instance's old name, if any # honor the hook name_set_closure = self.class.instance_variable_get :@name_set_closure ɴ = name_set_closure.( ɴ, self, old_ɴ ) if name_set_closure ɴ = self.class.send( :validate_capitalization, ɴ ).to_sym puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG return false if old_ɴ == ɴ # already named as required; nothing to do # otherwise, rudely remove the collider, if any pair = self.class.__instances__.rassoc( ɴ ) self.class.__forget__( pair[0] ) if pair # and add self to the namespace instead self.class.namespace.const_set ɴ, self # write a constant self.class.__instances__[ self ] = ɴ # write to __instances__ self.class.__forget__ old_ɴ # forget the old name of self return true end |
#name=(ɴ) ⇒ Object
Names an instance, cautiously (ie. no overwriting of existing names).
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/y_support/name_magic.rb', line 84 def name=( ɴ ) puts "NameMagic: Naming with argument #{ɴ}." if DEBUG # get previous name of this instance, if any old_ɴ = self.class.__instances__[ self ] # honor the hook name_set_closure = self.class.instance_variable_get :@name_set_closure ɴ = name_set_closure.call( ɴ, self, old_ɴ ) if name_set_closure ɴ = self.class.send( :validate_capitalization, ɴ ).to_sym puts "NameMagic: Name adjusted to #{ɴ}." if DEBUG return if old_ɴ == ɴ # already named as required; nothing to do # otherwise, be cautious about name collision raise NameError, "Name '#{ɴ}' already exists in " + "#{self.class} namespace!" if self.class.__instances__.rassoc( ɴ ) # since everything's ok... self.class.namespace.const_set ɴ, self # write a constant self.class.__instances__[ self ] = ɴ # write __instances__ self.class.__forget__ old_ɴ # forget the old name of self end |
#name_or_object_id ⇒ Object Also known as: ɴ_
Retrieves either an instance name (if present), or an object id.
77 78 79 |
# File 'lib/y_support/name_magic.rb', line 77 def name_or_object_id name || object_id end |