Skip to content

Instantly share code, notes, and snippets.

@bensummers
Created August 16, 2009 15:32
Show Gist options
  • Save bensummers/168648 to your computer and use it in GitHub Desktop.
Save bensummers/168648 to your computer and use it in GitHub Desktop.
Is this a hacky way to do annotations in ruby?
# Annotations module, enable in base class with "extend Annotations"
module Annotations
def method_added(method_name)
a = self.instance_variable_get(:@_annotated_next_method)
if a != nil
_annotation_storage(:@_annotated_methods,{})[method_name] = a
self.instance_variable_set(:@_annotated_next_method, nil)
end
super
end
def annotate_class(annotation_name, value)
_annotation_storage(:@_annotated_class)[annotation_name] = value
end
def annotate_method(annotation_name, value)
_annotation_storage(:@_annotated_next_method)[annotation_name] = value
end
def annotation_get(method_name, annotation_name)
m = self.instance_variable_get(:@_annotated_methods)
(m == nil) ? nil : m[method_name][annotation_name]
end
def annotation_get_class(annotation_name)
c = self.instance_variable_get(:@_annotated_class)
(c == nil) ? nil : c[annotation_name]
end
private
def _annotation_storage(name, default = nil)
a = self.instance_variable_get(name)
if a == nil
a = Hash.new(default)
self.instance_variable_set(name, a)
end
a
end
end
# ------------------------
# example annotations usage
module ExampleAnnotations
def exciting
annotate_method :exciting, true
end
def is_exciting?(method_name)
annotation_get(method_name, :exciting) == true
end
end
# ------------------------
# example classes
class Foo
extend Annotations
extend ExampleAnnotations
def carrots(og)
end
end
class Bar < Foo
# How's this syntax?
exciting; def carrots(pants)
end
def carrots2(fidh)
end
end
class Baz < Bar
# Or what about this syntax?
exciting
def something_or_other
end
annotate_class :something_or_other, :boo
end
class Bobble < Baz
def something_or_other
end
end
class Bobble2 < Bobble
exciting; def something_or_other
end
end
# ------------------------
def test_exciting(klass, method_name)
# Retrieve the value of the annotation
is_it_exciting = klass.is_exciting?(method_name)
# Debug out
puts "Method #{method_name} in class #{klass.name} #{is_it_exciting ? 'IS' : 'is not'} exciting"
end
test_exciting(Foo, :carrots)
test_exciting(Foo, :carrots_doesnt_exist)
test_exciting(Bar, :carrots)
test_exciting(Bar, :carrots2)
test_exciting(Baz, :something_or_other)
test_exciting(Bobble, :something_or_other)
test_exciting(Bobble2, :something_or_other)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment