Adding Annotations to JRuby Using Ruby
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:
I've planted the seed here and on the JRuby dev list...let's see if it germinates.
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.
Written on May 28, 2007