• 在ThoughtWorks工作已经有三个月了,快乐的事情在blog上体现了不少。找点让我头疼的话题聊聊吧!

    ThoughtWorks是个外企,所以,必然要大量的使用外语,而外语偏偏是我的弱项。当然,我没有不堪到一点英语不懂的份上。我的英语对付日常的读写没有什么问题,主要就是在听说上。我就是那种传统英语教导出来的哑巴英语,要不是之前和两个朋友曾经专门学过一段时间,我的英语恐怕到现在还是完全张不开嘴的水平,也就不可能能通过TW的面试。现在在北京的办公室里有不少来自其他办公室的同事,所以,不得不与他们进行交流。平时,有时还会有电话会议,原本听力就不那么好的我,再加电话里有些杂音,经常不知道对方在说什么。不过,自我感觉,这几个月下来英语还是有提高的,但为了如果想更好的与外国同事交流,英语还要进一步提高,这样的话,才可能讨论一些相对深入的话题。

    前两天,和老大聊天,他提到了中国人同其他国家人的一个差别。我们比较含蓄,通常会在深思熟虑之后,才提出自己的问题,他们通常会把自己想到的都摆在台面上。所以,这就造成了一些沟通上的障碍,有些时候,我们本来已经发现了问题,但常常会考虑该不该把问题提出来,把问题提出来会带来什么样的影响。结果,往往是在思前想后的阶段,就耽误了一些事。当然,完全展现自己的想法也并不一定就是好事,有一些明显错误的东西还是有些浪费大家时间。和一个在微软的同学聊天,他也提到,他们公司也是鼓励大家想法说出来。只有把想法说出来了,它才是存在的,否则,最后的结果可能就是消亡在自己的大脑中。

    现在在做的其实是一个产品方向,这就需要人有更加全面的能力。因为做项目的时候,我们往往只要关注特定的平台(OS、数据库、浏览器……),但是做产品要兼顾的内容就要广泛得多,有不少问题只有在特定的平台上才会显现出来,比如MySQL的数据库表名在Ubuntu下需要区分大小写,而在Windows上则不区分。这就暴露出我在这个方面的不足,我做过开发的平台其实并不多,所以,有些时候,我经常需要找同事来帮忙,还好,大家通常是只要自己知道,就会不遗余力的帮助你。

    现在我实际上是在一个分布式的团队中工作。说实话,我并不太喜欢这种工作方式,因为可能一个和你工作了很长时间的人,甚至都不知道长成什么模样。道理上没什么,但总不如直接在一起工作,那样的话,交流成本更低。我现在更容易理解为什么我们公司要让大家围坐在一起,这样,有话就说了,即便是一些无聊的话。再有,不熟悉的人总不如熟悉的人交流起来得自然,公司经常会有一些team building的活动,而且通常会鼓励不熟悉的人坐在一起,其目的就是为了大家增进了解,这样的话,在工作中就可以更好的进行沟通。而对于一个分布式团队来说,这一点就很难实现。

    之前做项目的时候,大多数时间都是拿到一个比较明确的任务,然后进行开发。而现在有些时候,某些任务并不是那么明确,虽然大的方向一直在那。仅仅拿远景说事,是不能完成任务的。这样的时候,是需要一些主管能动性让那些大目标变成一个个具体可行的目标。由于适应了之前那种工作方式,我经常会在那里等待。这在无形中就是一种浪费,对公司来说,也是一种损失。

    这样那样的问题,只能说明一点,对于我现在所从事的工作而言,我在某些方面还存在一些不足。发现不足是进步的基础,努力让自己成为一个更加合格的ThoughtWorker。
  • 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是个好东西,只是不知道它的出现是不是有些晚。
  • JRuby最近在讨论是否要支持Java 5。

    JRuby邮件列表的讨论
    http://www.nabble.com/Moving-to-Java-5--tf4131923.html

    InfoQ报道
    http://www.infoq.com/news/2007/07/jruby-java5-move
    http://www.infoq.com/cn/news/2007/07/jruby-java5-move

    XRuby起步就是从Java 5开始的,所以,不存在这个问题。在他们还在为此争论的时候,受到Charles Nutter最开始那封邮件的启发,我已经完成了Annotation标记Java代码和Ruby代码绑定的第一个版本。

    下面是一个例子:
    @RubyLevelClass(name="ClassFactory")
    public class ClassFactoryValue extends RubyValue {
        ...        
        @RubyLevelMethod(name="test", type=MethodType.NO_ARG)
        public RubyValue test() {
            return RubyConstant.QNIL;
        }
    }

    首先,用@RubyLevelClass标记出这个Java类对应着一个Ruby层次上的类,其名称为ClassFactory。然后,用@RubyLevelMethod标记出一个Java方法是对应着Ruby的方法,它的Ruby名称为test,而且它是无参数的。

    我们可以这样利用这段代码:
    RubyClass klass = RubyTypeFactory.getClass(ClassFactoryValue.class);

    通过RubyTypeFactory,我们可以生成ClassFactoryValue将Java层次和Ruby层次对应起来的代码,生成代码大致如下:
    public class ClassFactoryValue$ClassBuilder implements RubyClassBuilder {
        public RubyClass createRubyClass() {
            RubyClass rubyclass = RubyAPI.defineClass("ClassFactory", RubyRuntime.ObjectClass);
            MethodFactory methodfactory = MethodFactory.createMethodFactory(ClassFactoryValue.class);
            rubyclass.defineMethod("test", methodfactory.getMethod("test", MethodType.NO_ARG));

            return rubyclass;
        }
    }

    这里用之前介绍过的生成方法Wrapper的MethodFactory去辅助代码生成,简化了编写。

    XRuby本身为了生成bytecode已经做了大量的代码生成,这里只是把代码生成更多的用在了其他的部分。把这里的Annotation更广泛的用在XRuby中,会让代码看上去更干净。
  • 2007年,亚洲杯冠军,伊拉克足球队。

    谁都知道,现在的伊拉克是个什么样子。来自这个国家的球队,能够出现在亚洲杯决赛圈已经不易,更何况一步一步登上了亚洲之巅。在决赛场上,我们看到的内容已经远远超出足球的技战术范围。困境中的伊拉克爆发出惊人的战斗力,让对面的对手完全失去了自己的方向。战至最后阶段,伊拉克的队员几乎完全体力透支,但他们依然不断拼搏,将胜利拿下。

    伊拉克太需要胜利了,这个遍体疮痍的国家需要胜利,这种胜利会给这个民族注入他们目前最需要的信心。信心,对个人,对民族都至关重要,尤其当几乎一切都在一种最糟糕的状态下,这是一针强心剂。

    我不想讨论比赛,毕竟这只是一场亚洲的比赛,但我喜欢这样结果。在极大的压力下,人们往往会发挥超出自身实力的能力,会让观者得到极大的鼓舞,这就是竞技体育一个重要魅力。

    精神胜利的典范应该是意大利的足球。
    1982年,意大利在假球丑闻中成为了世界杯冠军。
    24年后,2006年世界杯,电话门丑闻,意大利队又一次坚强的笑到了最后。
    电话门丑闻使得AC米兰新赛季从一开始就不被人看好,但正是在这样的不利中,他们成为了2007年欧洲冠军联赛的冠军。

    我喜欢这样的足球,精神的胜利带给人们的享受远远大于竞技的内容,虽然那是一种迫不得已的无奈。

    恭喜,亚洲足球的新科状元,伊拉克足球队。