Brian's Waste of Time

Sat, 27 Aug 2005

Leo's Blogging Again!

I'm glad Leo has returned from his "escape geekery" sabbatical! In particular I'd like to point out a post on changing how we write jarvar =)

Leo gives us some code:

iterate(
      over( pairs(coll) ) )
    .skipIf(  keyIsInstanceOf(UnprocessableObject.class)  )
    .returning(  arrayOf(Pair.class)  )
    .exec(
      new Object(){Object process(Pair pair){
        print(  "%s -> %s", pair.getKey(), pair.getValue()  );
      }}  );  

What caught my eye is that it looks like a bunch of stuff I've been doing lately when building API's:

handle.inTransaction(new TransactionCallback() {
    public void inTransaction(Handle handle) throws Exception {
        handle.prepareBatch("insert into something (id, name) values (:id, :name)")
            .add(new Something(1, "one"))
            .add(new Something(2, "two"))
            .add(new Something(3, "three"))
            .add(Args.with("id", new Long(4)).and("name", "four"))
            .add(Args.with("id", new Long(5)).and("name", "five"))
            .execute();
    }
});
assertEquals(new Integer("5"),
             handle.first("select count(*) num from something")
                   .get("num"));

or

AsyncHelper.tryUntilNotInterrupted(new AsyncHelper.Helper() {
    public void cycle() throws InterruptedException {
        pendingWriteFrames.put(new FrameBuilder(Stomp.Responses.ERROR)
                        .addHeader(Stomp.Headers.Error.MESSAGE, message)
                        .toFrame());
    }});
}

which a popular couple libraries with reasonably well respected client api tends to do

return (Thing) getHibernateTemplate().execute(new HibernateCallback() {
    public Object doInHibernate(Session session) throws HibernateException {
        return session.createQuery("select s from Thing s where " +
                                   "s.wombat = :wombat and " +
                                   "s.mouse = :mouse")
                .setString("wombat", wombat)
                .setString("mouse", mouse)
                .uniqueResult();
    }
});

All of these examples use a common idiom from Ruby, Objective-C, and (I am told) Smalltalk -- message chaining. It leads to some really natural feeling and expressive code (which can look awfully funny at first, but you get used to it really fast, and then get frustrated when you cannot use it.

Next time you write a method with no return (a void method) consider having it return this instead. It breaks JavaBeans, sadly, which explicitely say a setter returns void, which limits its usability as the JavaBean naming convention is one of Java's serious strong points. It works nicely for chaining action style things though!

I blame Ruby. Leo blames Python. Gavin has blamed Smalltalk (he doesn't look old enough to be a Smalltalker, who'd have thunk). I don't know who gets blamed for the callbacks and templates in Spring, or to what they attribute the practice =)

2 writebacks [/src] permanent link

Stomp Notes

First, stomp won. It was close. =)

Second, am revoking the RC status to make a (backwards compatible) protocol change. Chatting with James and Joe (Joe is doing a .NET client, woot!) while fighting with WebLogic lead to an easy way to handle transactional consumes, so I'm going to finish up client ack and add support for transactional message acceptance before calling it 1.0. As Joy is out of town, that means probably by Sunday night =)

The haus kindly offered to host work, so if you're making a client, building an adaptor, or implementing a server in Erlang, drop me a note.

Oh yeah, James noted that a JDK 1.1 compatible client would be possible over on TSS when someone asked about it =) JMS on JDK 1.1, who'd have thunk.

0 writebacks [/src/stomp] permanent link