Module: Annotable

Defined in:
lib/annotable.rb,
lib/annotable/method.rb,
lib/annotable/version.rb,
lib/annotable/annotation.rb

Overview

Annotable is a module that can extend any class or module to add the ability to annotate its methods.

class Needy
  extend Annotable # Extend your class or module with Annotable
  annotable :my_annotation, :my_other_annotation # Declare your annotations

  my_annotation 42, hello: "world!" # Annotate your methods
  def 
    # ...
  end

  def regular_method
    # ...
  end
end

‘Annotable` adds several methods to your class or module, providing access to annotations and their metadata:

Needy.annotated_method_exist? :method_needing_meta_data # => true
Needy.annotated_method_exist? :regular_method # => false
Needy.annotated_methods
# => [#<Annotable::Method
#   @annotations=[
#     #<Annotable::Annotation
#       @name=:my_annotation,
#       @options={:hello=>"world!"},
#       @params=[42]>
#   ],
#   @name=:method_needing_meta_data>
# ]

‘Annotable::Method` represents a method name along with its annotations:

method = Needy.annotated_methods.first
method.name # => :method_needing_meta_data
method.annotations
# => [
#   #<Annotable::Annotation
#     @name=:my_annotation,
#     @options={:hello=>"world!"},
#     @params=[42]>
# ]

‘Annotable::Annotation` contains annotation’s name and metadata:

annotation = method.annotations.first
annotation.name # => :my_annotation
annotation.params # => [42]
annotation.options # => {:hello => "world!"}

Defined Under Namespace

Classes: Annotation, Method

Constant Summary collapse

VERSION =

Returns The gem version number.

Returns:

  • (String)

    The gem version number

"0.2.0"

Instance Method Summary collapse

Instance Method Details

#annotable(*annotation_names) ⇒ void

This method returns an undefined value.

Declares annotations usable in the module or class.

annotable :my_annotation, :my_other_annotation

This will generate two class methods named after the given symbols. These methods will push a new ‘Annotation` instance in the `current_annotation` array.

Parameters:

  • annotation_names (Array<Symbol>)

    The names of annotations to declare

Raises:

  • (ArgumentError)


71
72
73
74
75
76
77
78
79
# File 'lib/annotable.rb', line 71

def annotable(*annotation_names)
  raise ArgumentError, "You must provide at least one annotation name" if annotation_names.empty?

  annotation_names.each do |name|
    define_singleton_method(name) do |*params, **options|
      current_annotations.push Annotable::Annotation.new(name, params, options)
    end
  end
end

#annotated_method_exist?(name) ⇒ Boolean

Check if an annotated method exists based in its name.

Parameters:

  • name (Symbol)

    The name to check

Returns:

  • (Boolean)

    True if the annotated method exists, false otherwise



143
144
145
# File 'lib/annotable.rb', line 143

def annotated_method_exist?(name)
  !annotated_methods.find { |am| am.name == name }.nil?
end

#annotated_methods(*names) ⇒ Array<Annotable::Method>

Return all annotated methods or those matching the given annotation names.

Parameters:

  • names (Array<Symbol>)

    The annotation names to find

Returns:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/annotable.rb', line 121

def annotated_methods(*names)
  return @annotated_methods if @annotated_methods.empty? || names.empty?

  @annotated_methods.select do |method|
    annotation_found = false

    names.each do |name|
      annotation_found = method.annotation_exist?(name)
      break if annotation_found
    end

    annotation_found
  end
end

#annotation(name) {|params, options| ... } ⇒ void

This method returns an undefined value.

Declares one annotation usable in the module or class. The annotation can be validated using a block.

annotation :my_annotation do |params, options|
  raise ArgumentError, "my_annotation doesn't accept parameters" unless params.empty?

  case options
  in foo:
    raise ArgumentError, "foo must be a String" unless foo.is_a? String
  else
    raise ArgumentError, "foo is mandatory"
  end
end

This will generate a class method named after the given symbol. This method intialize a new ‘Annotation` which then execute the validation block. The annotation instance will be pushed in the `current_annotation` array.

Parameters:

  • name (Symbol)

    The names of annotations to declare

Yields:

  • (params, options)

    params and/or options validation block

Yield Parameters:

  • params (Array<Object>)

    the annotation parameters

  • options (Hash<Symbol, Object>)

    the annotation options



108
109
110
111
112
# File 'lib/annotable.rb', line 108

def annotation(name, &validator)
  define_singleton_method(name) do |*params, **options|
    current_annotations.push Annotable::Annotation.new(name, params, options, &validator)
  end
end