Class: Anise::Annotations::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/anise/annotations/store.rb

Overview

The Store class tracks annotations on a per-class bases.

Instance Method Summary collapse

Constructor Details

#initialize(space) ⇒ Store

Setup new Annotations instance.

Parameters:

  • space (Class, Module)

    Class or Module to have annotations.



14
15
16
17
# File 'lib/anise/annotations/store.rb', line 14

def initialize(space)
  @space = space
  @table = Hash.new { |h,k| h[k]={} }
end

Instance Method Details

#[](ref, ns = :ann) ⇒ Object

Access to local table.



30
31
32
# File 'lib/anise/annotations/store.rb', line 30

def [](ref, ns=:ann)
  @table[ns][ref]
end

#ancestorsObject

Ancestors of spaceal class/module.



20
21
22
# File 'lib/anise/annotations/store.rb', line 20

def ancestors
  @space.ancestors
end

#annotate(ns, ref, keys_or_class, keys = nil) ⇒ Object

Set or read annotations.

IMPORTANT! Do not use this for in-place modifications. Use #annotate! instead.

Parameters:

  • ref (Object)

    Annotation reference key.

Since:

  • 0.7.0



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/anise/annotations/store.rb', line 72

def annotate(ns, ref, keys_or_class, keys=nil)
  if Class === keys_or_class
    keys ||= {}
    keys[:class] = keys_or_class
  else
    keys = keys_or_class
  end

  if Hash === keys
    update(ns, ref, keys)
  else
    key = keys.to_sym
    lookup(ref, ns)[key]
  end
end

#annotate!(ns, ref, keys_or_class, keys = nil) ⇒ Object

To change an annotation’s value in place for a given class or module it first must be duplicated, otherwise the change may effect annotations in the class or module’s ancestors.

Parameters:

  • ref (Object)

    Annotation reference key.

Since:

  • 0.7.0



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/anise/annotations/store.rb', line 97

def annotate!(ns, ref, keys_or_class, keys=nil)
  if Class === keys_or_class
    keys ||= {}
    keys[:class] = keys_or_class
  else
    keys = keys_or_class
  end

  if Hash === keys
    update(ns, ref, keys)
  else
    key = keys.to_sym
    @table[ns][ref] ||= {}
    begin
      @table[ns][ref][key] = lookup(ref, ns)[key].dup
    rescue TypeError
      @table[ns][ref][key] = lookup(ref, ns)[key]
    end
  end
end

#localObject

Annotations local to spaceal class/module.



25
26
27
# File 'lib/anise/annotations/store.rb', line 25

def local
  @table
end

#lookup(ref = nil, ns = :ann) ⇒ Object

Lookup an annotation. Unlike ‘self` this provides a complete annotation heritage, pulling annotations of the same reference name from ancestor classes and modules.

Unlike the other annotation methods, this method takes the ‘ref` argument before the `ns` argument. This is it allow `ns` to default to the common annotator `ann`.

Parameters:

  • ref (Object) (defaults to: nil)

    Annotation reference key.

  • ns (Symbol) (defaults to: :ann)

    Annotation namespace.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/anise/annotations/store.rb', line 47

def lookup(ref=nil, ns=:ann)
  return @table if ref.nil?

  ref, ns = ref.to_sym, (ns || :ann).to_sym

  ann = {}
  ancestors.reverse_each do |anc|
    next unless anc.is_a?(Annotations)
    if h = anc.annotations.local[ns][ref]
      ann.merge!(h)
    end
  end
  return ann
end

#update(ns, ref, hash) ⇒ Object

Update annotations for a given namespace and reference.



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/anise/annotations/store.rb', line 119

def update(ns, ref, hash)
  ref  = ref.to_sym

  @table[ns][ref] ||= {}

  hash.each do |k,v|
    @table[ns][ref][k.to_sym] = v
  end

  # callback
  @space.annotation_added(ref, ns) #if method_defined?(:annotation_added)
end