I love how meta-programmable Ruby is.
JRuby doesn't support annotations because Ruby doesn't support annotations. So what! We can extend Ruby to add something like annotations:
Given this, we can do things like the following:
class JPABean
def self.inherited(clazz)
@@annotations = {}
end
def self.anno(annotation)
@@last_annotation = annotation
end
def self.method_added(sym)
@@annotations[sym] = @@last_annotation
end
def self.get_annotation(sym)
return @@annotations[sym]
end
end
And here's some output from the resulting class:
class MyBean :sql => "SELECT * FROM stuff WHERE name = 'foo'"
def foo; end
anno :field => :hello_id
attr :hello
anno :field => :bar_in_table
attr_accessor :bar
end
So as you can see we really do have all the necessary requirements to annotate classes. Now what if we just had MyBean be a java.lang.Object extension and stuffed the annotations into the resulting generated class? We can already create real Java classes in this way, but with the above syntax and a little magic in the JRuby Java integration later, we've got annotation support in on Java classes too. This should enable things like Hibernate, JPA, and JUnit 4 to work with JRuby's Ruby-based classes. Or at least, I believe it to be possible. It just requires a little work to add annotation information to the resulting generated classes.
p MyBean.get_annotation(:foo)
p MyBean.get_annotation(:hello)
p MyBean.get_annotation(:bar=)
=>
{:sql=>"SELECT * FROM stuff WHERE name = 'foo'"}
{:field=>:hello_id}
{:field=>:bar_in_table}
I've planted the seed here and on the JRuby dev list...let's see if it germinates.