Created
August 16, 2009 15:32
-
-
Save bensummers/168648 to your computer and use it in GitHub Desktop.
Is this a hacky way to do annotations in ruby?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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