Module: NameMagic
- Defined in:
- lib/y_support/name_magic.rb
Overview
This mixin imitates Ruby constant magic and automates the named argument :name, alias :ɴ (Character “ɴ”, Unicode small capital N, generally stands for “name” ins YSupport). One can write:
require 'y_support/name_magic'
class Foo; include NameMagic end
Bar = Foo.new
and the resulting object will know its #name:
Bar._name_ #=> :Bar
Bar.full_name #=> "Foo::Bar"
Foo::Bar #=> <Foo:0x.....>
This is done by searching whole Ruby namespace for constants, triggered by the method #const_magic defined in the namespace mixin. (Once the object is named, subsequent constant assignments have no effects.) By default, the namespace is the class, in which NameMagic is included, but it is possible to prescribe another module as a namespace:
Quux = Module.new
class FooBar
include NameMagic
self.namespace = Quux
end
FooBar.new name: "Baz"
FooBar::Baz #=> NameError
Quux::Baz #=> <FooBar:0x.....>
When subclassing the classes with NameMagic included, namespace setting does not change:
class Animal; include NameMagic end
class Dog < Animal; end
class Cat < Animal; end
Dog.namespace #=> Animal
Cat.namespace #=> Animal
Livia = Cat.new
Cat.instances._names_ #=> []
Animal.instances._names_ #=> [:Livia]
To make the subclasses use each their own namespace, use #namespace! method:
Dog.namespace!
NameMagic also provides an alternative way to create named objects by taking care of :name (alias :ɴ) named argument of the constructor:
Dog.new name: "Spot"
Dog.new
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
Retrieves the instance name.
-
#_name_ ⇒ Object
(also: #ɴ, #name)
Retrieves the instance’s name not prefixed by the namespace as a symbol.
-
#avid? ⇒ Boolean
Is the instance avid for a name? (Will it overwrite other instance names?).
-
#full_name ⇒ Object
Returns the instance’s full name, a string in the style of those returned by Module#name method, eg.
-
#inspect ⇒ Object
Default
#inspectmethod forNameMagicincluders. -
#make_not_avid! ⇒ Object
Make the instance not avid.
-
#name!(name) ⇒ Object
Names an instance, aggresively (overwrites existing names).
-
#name=(name) ⇒ Object
Names an instance, cautiously (ie. no overwriting of existing names).
-
#name_set_hook(&block) ⇒ Object
Registers a hook to execute upon instance naming.
-
#namespace ⇒ Object
The namespace of the instance’s class.
-
#to_s ⇒ Object
Default
#to_smethod forNameMagicincluders, returning the name.
Class Method Details
.included(target) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/y_support/name_magic.rb', line 76 def self.included target if target.is_a? Class then # decorate #new target.singleton_class.class_exec do # Primer that sets the namespace of the class to self if the user has # not defined otherwise when this method is first called. # define_method :namespace do target.extend ::NameMagic::NamespaceMethods define_singleton_method :namespace do target end # redefines itself namespace end end target.singleton_class.class_exec { prepend ::NameMagic::ClassMethods } else # it is a Module -- infect it with this #include orig, this = target.method( :included ), method( :included ) target.define_singleton_method :included do |m| this.( m ); orig.( m ) end end end |
Instance Method Details
#__name__ ⇒ Object
Retrieves the instance name. Does not trigger #const_magic before doing so.
124 125 126 127 |
# File 'lib/y_support/name_magic.rb', line 124 def __name__ |
#_name_ ⇒ Object Also known as: ɴ, name
Retrieves the instance’s name not prefixed by the namespace as a symbol. Underlines (#name) distinguish this method from #name method, which returns full name string for compatibility with vanilla Ruby Module#name.
105 106 107 108 |
# File 'lib/y_support/name_magic.rb', line 105 def _name_ self.class.const_magic __name__ or ( yield self if block_given? ) end |
#avid? ⇒ Boolean
Is the instance avid for a name? (Will it overwrite other instance names?)
163 164 165 |
# File 'lib/y_support/name_magic.rb', line 163 def avid? namespace.__avid_instances__.any? &method( :equal? ) end |
#full_name ⇒ Object
Returns the instance’s full name, a string in the style of those returned by Module#name method, eg. “Namespace::Name”.
116 117 118 |
# File 'lib/y_support/name_magic.rb', line 116 def full_name "#{namespace.name || namespace.inspect}::#{namespace.instances[ self ]}" end |
#inspect ⇒ Object
Default #inspect method for NameMagic includers.
192 193 194 |
# File 'lib/y_support/name_magic.rb', line 192 def inspect to_s end |
#make_not_avid! ⇒ Object
Make the instance not avid.
169 170 171 |
# File 'lib/y_support/name_magic.rb', line 169 def make_not_avid! namespace.__avid_instances__.delete_if { |i| i.object_id == object_id } end |
#name!(name) ⇒ Object
Names an instance, aggresively (overwrites existing names).
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/y_support/name_magic.rb', line 149 def name!( name ) old_ |
#name=(name) ⇒ Object
Names an instance, cautiously (ie. no overwriting of existing names).
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/y_support/name_magic.rb', line 131 def name=( name ) old_ |
#name_set_hook(&block) ⇒ Object
Registers a hook to execute upon instance naming. Instance’s ‘#name_set_hook` Behaves analogically as namespace’s ‘#name_set_hook`, and is executed right after the namespace’s hook. Expects a block with a single argument, name of the instance. The return value of the block is not used and should be nil. Without a block, this method acts as a getter.
179 180 181 182 |
# File 'lib/y_support/name_magic.rb', line 179 def name_set_hook &block tap { @name_set_hook = block } if block @name_set_hook ||= -> name { nil } end |
#namespace ⇒ Object
The namespace of the instance’s class.
97 98 99 |
# File 'lib/y_support/name_magic.rb', line 97 def namespace self.class.namespace end |
#to_s ⇒ Object
Default #to_s method for NameMagic includers, returning the name.
186 187 188 |
# File 'lib/y_support/name_magic.rb', line 186 def to_s name ? name.to_s : super end |