• XRuby0.3.0发布了!恰好今天是奥运倒计时一周年,所以,这个版本顺理成章的成了纪念版。

    在这个版本中,除了让更多单元测试通过之外,最大的变化是在Annotation的应用上。关于Annotation的工作,我已经在自己的blog上讨论过一些,这里再整理一下。

    Ruby的方法总要有一个对应的底层语言实现。在C Ruby中,这个对应就是一个C的函数,而定义的时候,直接使用函数指针去做这个关联。而在Java中,因为没有函数指针,作为替代方案,我们可以使用一个对象。在XRuby的实现中,RubyMethod的存在就是为了这个目的。所以,在XRuby中对应到Ruby的方法都源自RubyMethod,比如下面这段代码:

    public class String_to_f extends RubyNoArgMethod {
       protected RubyValue run(RubyValue receiver, RubyBlock block) {
           return ((RubyString)receiver).to_f();
       }
    }

    从上面展示的代码中,我们可以看到,为了实现这段方法,最终需要访问receiver的内容,而且,在事实的开发中,我们经常发现一个两难的抉择:究竟把方法的具体实现放在RubyMethod中还是放在Java的方法中。

    有了对应的实现,我们还需要将它注册到系统中:
    StringClass.defineMethod(“to_f”, new String_to_f());

    这段虽然不复杂,重复编写也不是一件让人愉快的事情。

    通过Annotation,我们可以更好的解决这个问题,下面便是对应于上面实现的代码:

    @RubyLevelClass(name="String")
    public class RubyString {
        @RubyLevelMethod(name="to_f")
        public RubyFloat to_f() {
            ...
        }
    }

    在这里,我们使用RubyLevelMethod将一个Java的方法和Ruby的方法绑定在一起,这个Annotation表示,一方面会生成一个对应于这个方法的RubyMethod实现满足调用规则,另一方面会在Ruby的类中定义出这个方法,减少了一些重复编码的工作量。使用Annotaion避免了前面提及的那种两难,所有的方法都实现在Java方法中即可,这样,便可以有效的减少设计上的迷惑。再有,这个Annotation可以让Java方法和Ruby方法的关联一目了然。

    一如既往的欢迎对XRuby有兴趣的人加入到XRuby的开发中来,在这里,总是有一些有趣的问题可以解决。
  • 因为给XRuby做代码标记的原因,最近一直在Annotation和打交道。在我看来,Annotation是Java 5所有新语言特性中,唯一很难一下子看清楚的特性。其它的特性只要用JAD反编译一下生成的字节码,就一目了然了。我手头的JAD只能处理1.4的字节码,所以,Annotation的某些特性并不能直接反编译出来,比如缺省值。从现实的情况来看,Annotation已经开始有一些不错的应用,比如EJB 3.0,比如JUnit 4。

    从为XRuby写代码的经验来看,Annotation真的是一个不错的东西,应用了Annotation之后,代码变得更加干净,XRuby的代码因此就变得清爽了不少。XRuby通过Annotation做了许多代码生成的工作,如果采用手工编码的方式,这些代码没有难度,只有复杂度。重复的代码写起来,只会让人感到繁琐。

    XRuby中运用Annotation的方式本质上相当于在做编译器的工作。对Annotation的解析,相当于parser解析源代码,当然,相对于parser来说,解析Annotation要简单得多。之后的过程就是类似的过程,根据前面解析的结果对应着进行代码生成。

    在实现XRuby Annotation的过程中,还有一些有趣的工作。比如如何设计Annotation。最初的设计中,RubyLevelMethod有一个type属性,用以标识方法的类型,主要是为了满足XRuby一些优化手段,比如对于无参数和一个参数的方法调用,会做一些特殊处理提高性能。不过,这样的方法通常会有一些特别的签名,这样的签名完全是可以检测出的,所以,实际上这个type属性并不需要,而且,偶尔的误操作(比如无参数方法的type写成了一个参数),还会抛出异常。所以,最终type这个属性被去掉了,当然,这么做需要额外付出一些努力,不过,相对而言,这种努力是值得的。这个问题实际上类似于语言设计一样,哪些东西设计到语言里,哪些部分是隐含可以得到的。

    Annotation可以给我们一些提示,通过诸如代码生成等工作,从而把一些操作从原来的硬编码的方式中转移出去,比如事务,AOP等等。我相信,这样会带来一些设计思路的转变,从而更好的进行设计上的划分。更进一步,设计中完全可以加入更多的业务特性,也就会让代码更有DSL的味道。

    对比于Java中常见的XML方式,我更喜欢Annotation。首先,它和代码结合的更紧密,这样,在阅读的时候,可以更直观的去理解一些东西,而XML的方式中,秘密都在另外的地方。其次,IDE工具可以很好的联系源码,做一些查找引用某些类的情况就会简单得多。当然,有个问题,每次修改可能都需要重新编译代码,这个问题在开发XRuby Annotation的过程中经常遇到。

    InfoQ的Floyd前不久在BEA User Group的活动中谈及企业级Java前景时,提到了他认为几个重要的趋势,包括POJO、IoC(DI),再有就是Annotation。在对Annotation有了更多的了解之后,我认为Annotation是个好东西,只是不知道它的出现是不是有些晚。