Module: Anise::Annotative::Attributes

Includes:
Anise::Annotations
Defined in:
lib/anise/annotative/attributes.rb

Overview

TODO:

Currently annotated attributes alwasy use the standard annotator (:ann). In the future we might make this customizable.

The Attributes mixin modifies the attr_* methods to allow easy addition of annotations for attributes. It modifies the built in attribute methods (attr, attr_reader, attr_writer and attr_accessor), and any other custom ‘attr_*` methods, to allow annotations to be added to them directly rather than requiring a separate annotating statement.

class X
  extend Anise::Annotative::Attributes

  attr :a, :valid => lambda{ |x| x.is_a?(Integer) }
end

See Annotation module for more information.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Anise::Annotations

#ann, #ann!, #annotation_added, #annotations

Class Method Details

.define_annotated_attribute(base, attr_method_name) ⇒ Object

Define an annotated attribute method, given an existing non-annotated attribute method.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/anise/annotative/attributes.rb', line 49

def self.define_annotated_attribute(base, attr_method_name)
  base.module_eval do
    define_method(attr_method_name) do |*args|
      args.flatten!

      harg={}; while args.last.is_a?(Hash)
        harg.update(args.pop)
      end

      raise ArgumentError if args.empty? and harg.empty?

      if args.empty?  # hash mode
        harg.each { |a,h| __send__(attr_method_name,a,h) }
      else
        klass = harg[:class] = args.pop if args.last.is_a?(Class)

        super(*args) #attr_method.call(*args)

        args.each{|a| ann(a.to_sym,harg)}

        instance_attributes!.concat(args)  #merge!

        # Use this callback to customize for your needs.
        if respond_to?(:attr_callback)
          attr_callback(self, args, harg)
        end

        # return the names of the attributes created
        return args
      end
    end
  end
end

.extended(base) ⇒ Object

When included into a class or module, Annotation is also included and Attribute::Aid extends the class/module.

Parameters:

  • base (Class, Module)

    The class or module to get features.



34
35
36
37
38
39
40
41
# File 'lib/anise/annotative/attributes.rb', line 34

def self.extended(base)
  #inheritor :instance_attributes, [], :|
  base_class = (class << base; self; end)
  #base_class.attribute_methods.each do |attr_method|
  base.attribute_methods.each do |attr_method|
    define_annotated_attribute(base_class, attr_method)
  end
end

Instance Method Details

#attr(*args) ⇒ Object

This defines a simple adjustment to #attr to allow it to handle the boolean argument and to be able to accept attributes. It’s backward compatible and is not needed for Ruby 1.9 which gets rid of the secondary argument (or was suppose to!).



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/anise/annotative/attributes.rb', line 127

def attr(*args)
  args.flatten!
  case args.last
  when TrueClass
    args.pop
    attr_accessor(*args)
  when FalseClass, NilClass
    args.pop
    attr_reader(*args)
  else
    attr_reader(*args)
  end
end

#classified_attributesObject

Return list of attributes that have a :class annotation.

class MyClass
  attr_accessor :test
  attr_accessor :name, String, :doc => 'Hello'
  attr_accessor :age, Fixnum
end

MyClass.instance_attributes # => [:test, :name, :age, :body]
MyClass.classified_attributes # => [:name, :age]


116
117
118
119
120
# File 'lib/anise/annotative/attributes.rb', line 116

def classified_attributes
  instance_attributes.find_all do |a|
    self.ann(a, :class)
  end
end

#instance_attributesObject

Instance attributes, including inherited attributes.



86
87
88
89
90
91
92
93
94
95
# File 'lib/anise/annotative/attributes.rb', line 86

def instance_attributes
  a = []
  ancestors.each do |anc|
    next unless anc < Attributes
    if x = anc.instance_attributes!
      a |= x
    end
  end
  return a
end

#instance_attributes!Object

Local instance attributes.



100
101
102
# File 'lib/anise/annotative/attributes.rb', line 100

def instance_attributes!
  @instance_attributes ||= []
end