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[ref] 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