module Anise
require 'anise/annotation'
# = Annotator
#
# The Annotator module allows for the creation of method annotations
# which attach to the next method defined.
#
# This idiom of annotator-before-definition was popularized by
# Rake's desc/task pair. The Annotator module makes it very easy
# to add similar capabilites to any program.
#
# require 'anise/annotator'
#
# class X
# include Anise::Annotator
#
# annotator :doc
#
# doc "See what I mean?"
#
# def see
# puts "Yes, I see!"
# end
# end
#
# X.ann(:see, :doc) #=> "See what I mean?"
#
# Note that the library uses the #method_added callback, so be sure to
# respect good practices of calling +super+ if you need to override
# this method while using Annotator.
#
#--
# TODO: Allow annotators to be inherited via module mixins.
#
# TODO: Ensure thread-safety of @_pending_annotations
variable.
#++
module Annotator
#
def self.append_features(base)
Annotation.append_features(base) #unless base.is_a?(Annotation)
base.extend ClassMethods
super(base)
end
module ClassMethods
# Define an annotator.
def annotator(name, &block)
(class << self; self; end).module_eval do
define_method(name) do |*args|
@_pending_annotations ||= []
@_pending_annotations << [name, args, block]
end
end
end
# When a method is added, run all pending annotations.
def method_added(sym)
@_pending_annotations ||= []
@_pending_annotations.each do |name, args, block|
if block
block.call(sym, *args)
else
if args.size == 1
ann(sym, name=>args.first)
else
ann(sym, name=>args)
end
end
end
@_pending_annotations = []
super if defined?(super)
end
end
end
end
# Copyright (c) 2005,2011 Thomas Sawyer