• XRuby:享用JVM上的Ruby

    在InfoQ China发了一篇介绍XRuby的文章。其实,对于之前听过我介绍XRuby的人来说,这篇文章的内容并不新鲜,因为基本上,这篇文章的内容脱胎于之前介绍XRuby的讲稿。虽然讲了几次,但还是应该把这篇文章写出来。一来,到场听介绍的人毕竟是少数,写出来看到的人应该可以更多,也让更多的人有机会了解XRuby,再有,内容写成文章需要比演讲时有更多的思考。所以,整体来说,内容叙述应该会更加准确。

    这是一篇早就该写的文章,至少最初答应霍泰稳写这篇文章还是5月份的时候,7月份录我InfoQ访问的时候,又答应了Floyd完成这篇文章,可真正发布已经是十月份了。不过,这样一拖再拖也不是完全价值。在这段时间里,我在Agile Day讲了一次Ruby on JVM,让我对这个方面有了些新的思考,特别是把Ruby放在 JVM上的价值,这一点已经体现在这篇文章里了。另外,XRuby自身在这段时间中也发生了很大的变化,特别是Annotation的加入,让代码在表现形式上得到很大的进步。至少在我看来,最终体现在文章中的示例代码是可以接受的。

    我希望,这篇文章可以成为一个起点。一方面,它可以作为让更多人了解XRuby的起点;另一方面,XRuby团队把它作为一个起点,向其它人展示XRuby中非常优秀的一面。当然,XRuby现在已经有了不少不错的文档。

    已经有朋友给我建议,写一些更深入的东西,这也是我所希望的,只探讨一些比较浅的东西不过瘾。在XRuby开发过程中,有很多有趣的思考,我很愿意与人分享那种开发中的快乐。再有,写东西会促使人思考,随之而来的往往是发现不足,这也是有益于XRuby进一步改进的。

    如果你希望了解或参与XRuby,不妨告诉我们,你想了解什么,也许,我们之后的文章会满足你!
  • 今天是一个发布的日子,XRuby发布了0.3.1,Ruby Hacking Guide中文版发布了第一部分。

    XRuby 0.3.1

    相比于前一个版本,XRuby 0.3.1最大的进步在于完成标准库的预编译。预编译意味着什么?标准库代码无需在每次运行时编译,这意味着今后使用XRuby的标准库性能会得到一定的提升。

    有一个与编译相关的话题。之前,Jon Tirsen曾经谈到JRuby的一个问题,运行在AppServer中会有占用太多内存。经过分析得知,为了提高程序的并发性,程序运行会启动多个JRuby。每个JRuby解析Ruby脚本都会建立一棵完整的语法树,这就意味着,由于这种解析模式本身的限制,对于同样的内容,内存中需要保存多份相同的语法树,这种做法意味着无谓的耗用了大量的内存。采用编译的做法,则可以很好的避免这个问题。因为在运行时,相同的是字节码,而JVM很好的帮我们解决字节码共享问题,无需耗用大量的内存。

    Ruby Hacking Guide中文版第一部分

    RHG终于完成了第一次发布。已经发布的第一部分介绍的是Ruby的对象模型。我正是从这个部分开始了解Ruby实现的,进而完成了XRuby的Runtime的重写。所以,我一直觉得这部分是了解Ruby实现非常好的一个起点。

    从翻译Ruby Hacking Guide到现在已经超过了一年,从第一次发布消息算起也超过了9个月。相比XRuby,这个项目的进展可以用异常缓慢形容。这是一本日文书,也是一本技术书,而且是一本讲语言实现的书。任何一个点都会增加翻译的难度。几个懂日语的朋友先进行一遍初译,然后,我对再对译稿进行一遍校验,并根据自己的理解修改译稿,这样的过程无疑延长了处理的时间。这是一个业余时间的项目,而我更多的业余时间在XRuby上,没有太多精力投入上面。种种的因素造成了这个项目的一托再托。

    目前,我手头已经有了第二部分全部和第三部分几章的初译稿,不过,按照之前的进度来看,这几章的发布可能要等到许久之后了。如果你有兴趣,可以加入到这个项目中来,这样,有助于加快这个项目的进度。

  • 一年前,yawl将自己用业余时间做了一年的项目开源了,这就是XRuby。
    XRuby project is now hosted on Google Code
    有人愿意做Ruby Compiler么?

    我就是那时加入XRuby的,依然记得最初见到这个项目时的兴奋,转眼,一年过去了。从2007年1月29日0.1.0发布至今,我们一共发布了7个版本。XRuby正逐渐变得越来越有样子:代码越来越干净,功能越来越强大。

    XRuby是我第一次真正全身心投入参与的一个开源项目:常常为自己漂亮的解决了一个问题而自豪,也时常为解决方案不够优雅而寝食难安。依然记得有几次,为了实现一个功能而熬夜;也有本来已经躺在床上,却难以抑制兴奋爬起来继续编码。这一年里,XRuby在成长,我也随着这个项目在成长,对Ruby语言的实现理解越来越深,从最开始的照搬C实现,到现在逐渐有了一些自己的想法在里面。在与大家合作的过程中,从其它人身上学到了许多足以让我受用终身的东西,尤其是yawl。相信其他深入参与XRuby的人与我有着类似的经历和感受吧!

    其实,在这一年里,我也并非始终如一的对XRuby付出着。从项目最初开源到发布0.1.0之间有大约4个多月时间,完成了那个新runtime之后,很长一段时间,我并没有写太多代码。那段时间,应该是我参与XRuby过程,感觉最为黑暗的一段时间,因为确实看不到这个项目的方向,没有版本发布,漫无边际的代码等待着编写,而我写的新runtime又很难集成到XRuby里面。这个状态一直持续到0.1.0的发布,我似乎一下子看到了光明,尽管XRuby看起来那么不成熟,但我们的努力终于得到了一丝回报,于是,我兴奋的写下了《XRuby发布了!》 。

    在我找回动力之后,XRuby也逐渐开始得到了越来越多的关注,项目成员也逐渐增多,XRuby也逐渐步入开发的正轨。每隔一个多月,我们就会发布新版本,每次新版本的发布,都增强着我们对XRuby的信心。XRuby的成员也通过各种途径向大家介绍着XRuby,也有人开始讨论XRuby。

    做开源,最艰难的是什么?技术吗?似乎是,尤其像XRuby,仅仅一个“编译器”的名头,就足以让许多人望而却步了。其实不然,技术这东西,只有不愿意学的,少有难以学会的。参与XRuby并不需要一开始就掌握复杂的编译器技术,因为XRuby包括了许多部分,编译器只是其中的一个部分。时至今日,XRuby中的某些部分对我来说,依然是陌生的,但这并不影响我为XRuby编写代码。从个人的经历来看,builtin是一个很好的入手点,而那里并不多数情况下并不需要了解编译器,甚至几乎不需要了解Ruby内部实现。

    在我看来,最难的是坚持。用业余时间,无偿为一个项目付出着。回报?除了知识和技能上的提升,其他都是不可预期的。在这种情况下,坚持着实是一件困难的事情。其实大家可以很清楚的看出来,这个世界上,开源项目不计其数,但真正能让人知道的少之又少,许多开源项目在开始后没多长时间便死去了。在国内论坛中,很多开源项目的发起者都在抱怨,开源环境很差,没有人参与他们的项目。当然,这其中也有项目本身吸引力的因素。其实,做开源是需要一些理想主义的,这样,才能在一条未知的路上前行。XRuby中也存在类似的问题,许多参与者一开始总是兴致勃勃的要求加入,好一些的,贡献了一些代码之后,便很长时间没有声音,有的则在加入之后,一行代码都没有写,便无声无息了。从加入开始一直比较稳定的贡献代码的人,屈指可数。不过,从另一个角度,这也说明了,当一个开源项目具备了一定的生命力之后,并不会因为某个人的不作为而死去。

    不管一路上有多少阳光和风雨,XRuby走过了它的第一个生日,步入了第二个年头,大家已经开始尝试着进行Rails的支持,我们会努力让它走得更好。在班加罗尔讲XRuby时,有人问过我,现在XRuby面临的主要问题是什么,我说,我们没有足够的资源。其实,现在可以看到的很多问题对我们来说,并不是非常困难,但却需要投入大量时间来完成。这也是我们始终如一的欢迎有兴趣的人加入我们的原因。如果你愿意和XRuby一起成长,欢迎加入我们!

  • 做了一件让自己觉得不可思议的事情,在班加罗尔的Geek Night用英文讲XRuby。

    这周早些时候,在办公室遇到了Sidu——我在西安办公室见过他。周五有个班加罗尔Ruby User Group的活动,叫Geek Night,Sidu是活动的组织者。之前,他知道Ola会来,于是安排Ola介绍JRuby。当他看到我的时候,才知道我也来了班加罗尔,于是邀请我也一起参加活动。我问他,我是否需要准备什么,他建议我做一个XRuby的介绍。Ola会有一个45分钟左右JRuby方面的介绍,所以,我需要做的只是一个简单的XRuby介绍。很合我意,因为要用英文讲,所以,如果讲多了,我恐怕自己不成。我很快就准备好了一个很短的介绍。

    ThoughtWorks做事总是要敏捷的。今天,我发现Ola没来,后来才知道Ola病了。所以,Ola的部分就取消了。Sidu问我怎么办,我只好硬着头皮答应由我讲一个长一点的,一个比较完整的XRuby介绍。晚上六点的活动,商量好这些的时候,已经是四点多了。所幸之前讲过XRuby的介绍,我把讲稿翻出来修改了一番,更新了一些状态,准备用在活动中。XRuby介绍这个稿子居然得到了反复应用,第一次在北京Java User Group,第二次在敏捷西安,据说,XRuby的其他成员也用过。无论如何,我没想到,我个人的第三次居然是在班加罗尔,而且是英文。

    其实,最让我头疼的绝对不是介绍XRuby,而是用英文。这周在班加罗尔上课,对我来说,简直就是一周的英文课。所有课程所有讨论都是英文,我的英文水平让我经常就不知道大家在说什么。不过,自我感觉,经过一些锻炼之后,还是略有提高的。

    活动开始,我开始了第一次用英文在比较公开的场合讲东西。我的开场白是,这是我第一次用英文讲。起初,活动在一个小会议室进行,在我讲的过程中,进来的人越来越多,所以,我们又换到了一个比较大的会议室。因为用英文,我只能说,我尽量把我要表达的意思说出来,至于是否大家听懂了,我不好说。好在有讲稿,即便我讲得不够清楚,讲稿也会帮助大家多一些理解的。当翻到讲稿最后一页的时候,我长出了一口气。如果是用中文的话,我可以说得更多,至少我可以胡扯一些东西。对我来说,更大的挑战是Q&A。我的听力本来就不是太好,印度口音更是经常让我犯晕。开始之前,我找了几个同事,如果我听不懂的话,他们可以为我解释一下。在提问者的宽容和几位同事的帮助之下,我成功的度过了Q&A。问题倒不算太难,唯一让我不敢确认的是,我说的是否真的是我要表达的意思,希望没有大错。

    不管怎样,我用英文讲了一次XRuby,一次很有趣的经历。
  • 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的开发中来,在这里,总是有一些有趣的问题可以解决。