Module: Anise::Annotations
- Included in:
- Anise::Annotative::Attributes, Anise::Annotative::Methods, Anise::Annotative::Variables, Module
- Defined in:
- lib/anise/annotations.rb,
lib/anise/annotations/store.rb
Overview
The Annotation provides a framework for annotating class and module related objects, typically symbols representing methods, with arbitrary metadata. These annotations do not do anything in themselves. They are simply data. But they can be put to good use. For instance an attribute validator might check for an annotation called :valid and test against it.
The standard annotator is ‘:ann` and is the defualt value of annotating methods.
class X
extend Anise::Annotations
ann :a, :desc => "A Number"
attr :a
end
X.ann(:a, :desc) #=> "A Number"
As stated, annotations need not only annotate methods, they are arbitrary, so they can be used for any purpose. For example, we may want to annotate instance variables.
class X
ann :@a, :valid => lambda{ |x| x.is_a?(Integer) }
def validate
instance_variables.each do |iv|
if validator = self.class.ann(iv)[:valid]
value = instance_variable_get(iv)
unless validator.call(value)
raise "Invalid value #{value} for #{iv}"
end
end
end
end
end
Or, we could even annotate the class itself.
class X
ann self, :valid => lambda{ |x| x.is_a?(Enumerable) }
end
Although annotations are arbitrary they are tied to the class or module they are defined against.
Creating custom annotators used to entail using a special ‘#annotator` method, but this limited the way custom annotators could operate. The new way is to define a custom class method that calls the usual `#ann` method, but add in a namespace.
class X
def self.cool(ref, *keys)
ann "#{ref}/cool", *keys
end
end
X.cool(:a, :desc) #=> "Awesome!"
The result is exactly the same as before, but now the custom annotator has complete control over the process.
Defined Under Namespace
Classes: Store
Instance Method Summary collapse
-
#ann(ref, *keys) ⇒ Object
Get/set annotations.
-
#ann!(ref, *keys) ⇒ Object
Get/set annotations in-place.
-
#annotation_added(ref, ns = :ann) ⇒ Object
Callback method.
-
#annotations ⇒ Object
Access to a class or module’s annotations.
Instance Method Details
#ann(ref, *keys) ⇒ Object
Get/set annotations.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/anise/annotations.rb', line 94 def ann(ref, *keys) if ref.to_s.index('/') ref, ns = ref.to_s.split('/') else ns = :ann end ref, ns = ref.to_sym, ns.to_sym if keys.empty? annotations.lookup(ref, ns) else annotations.annotate(ns, ref, *keys) end end |
#ann!(ref, *keys) ⇒ Object
Get/set annotations in-place. Use this method instead of ‘#ann` when performing mass updates.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/anise/annotations.rb', line 113 def ann!(ref, *keys) if ref.to_s.index('/') ref, ns = ref.to_s.split('/') else ns = :ann end ref, ns = ref.to_sym, ns.to_sym if keys.empty? annotations[ref, ns] else annotations.annotate!(ns, ref, *keys) end end |
#annotation_added(ref, ns = :ann) ⇒ Object
Callback method. This method is called for each new annotation.
81 82 83 |
# File 'lib/anise/annotations.rb', line 81 def annotation_added(ref, ns=:ann) super(ref, ns) if defined?(super) end |