« February 2006 | Main | April 2006 »

March 26, 2006

Teaching Mr. Rails a Lesson on Productivity

Summary: this entry is a review of the best HTML editor in the world. It is also a bash on the text editor used by the creator of Rails. It also avoids all Java vs. Ruby/Rails hoopla, and instead focusses on HTML editing differences when using different tools. I hope that perhaps this might help at least some folks finally get over the Java vs Rails war and instead realize there is merit to a lot of the sides out there. For my latest thoughts on Rails itself, see here.

Ever since I was told that I was warming up to the importance of productivity in response to an entry about the importance of tools, I've been keeping an eye out on tools that greatly make me more efficient. Some do the simplest things: Adium, for example, automatically aliases buddies by looking through my Address Book.

Others, however, are more complex. Today, I want to compare the best tool I have in my toolbox, IntelliJ IDEA, to the equivalent tool used by the Rails crew that use OS X, TextMate. But rather than comparing Java vs. Ruby, which always leads to some ridiculous debate (which, by the way, is exactly what the Rails guys want), I'm going to focus on the HTML editing capabilities of both tools. What we'll find is that productivity hides in many places - not just in some silly framework.

Considering that all both Rails and Struts/WebWork/Wicket/RIFE/Tapestry/JSF/etc all end up having to edit a lot of HTML, perhaps that is a good place to look for key improvements in productivity. My application as of today, in terms lines of code, is made up of 70% Java and 30% HTML, so this seems like a pretty large chunk of work that we'd want to make sure we optimize.

About the tools

IDEA is a complete Java editor. It is written in Java, is a total memory hog, and does everything from Java GUI editing to debugging to refactoring. It also happens to include an HTML editor. IDEA costs roughly $500 and is free for open source developers.

TextMate is a general purpose text editor with built in syntax highlighting for a ton of languages, including HTML and JSP. It is quick to start up and has a very responsive UI. TextMate costs roughly $50.

Side by side comparison

In comparing the two tools, I'm going to look at the following aspects for HTML editing:

  • CSS editing
  • JavaScript support
  • Error reporting
  • Code formatting
  • Refactoring

Let's start off by looking at the CSS support, including error reporting for mistakes in your CSS:

IDEA:
idea1.png

A few things to note here:

  • Notice how "button.jpeg" is highlighted as red - that indicates that while the directory "../images" exists, the image does not. Very useful!
  • The run underline just after "background" indicates that the CSS is not currently well-formed.
  • Pressing ctrl-space brings up a list of valid choices. The values for those choices are also made available through autocomplete. That includes color pickers and lists of options, such as "left", "justify", and "center".
  • Note shown, but worth mentioning: you can see the W3C spec on a particular CSS attribute by pressing the same key combination you would use to see the JavaDocs of Java code.

TextMate:
textmate1.png

TextMate offers... just about nothing. The CSS is syntax highlighted, but that's about it. My image location typo is not pointed out, nor is the invalid CSS.

Winner: IDEA

Now let's look at JavaScript support and any intelligent language-related features that the products might offer.

IDEA:
idea2.png

Again, note the code completion support. See how IDEA recognizes that the window object has certain fields available and makes them easily available. IDEA also has basic refactoring support for renaming variables and functions. You can also "goto" a function definition in external files, such as prototype.js, by simply pressing ctrl-b.

Overall, it isn't nearly as good as the Java support, but it is certainly better than what TextMate offers:

textmate2.png

Again, all TextMate offers is syntax highlighting. Wait - is that an error in my CSS definition I see there? When I first saw that red underline, I was hoping that perhaps TextMate saw a problem. I was sadly let down when I realize that it was merely telling me that the "word" "css/main.css" is a typo. Gee, thanks TextMate - you're really saving me a lot of time by highlighting non-words as spelling errors. I appreciate the effort, but no thanks.

Winner: IDEA

Let's look at code formatting now. This includes features like auto-indent, intelligent indent rules, and auto-formatting. Sadly, there isn't much of a contest here either, judging by the options tab for text editing.

IDEA:
idea3.png

A few things are worth pointing out:

  • As an HTML writer, I often like to indent my HTML, except in a few cases where it causes too much unnecessary whitespace. Why, look at that: IDEA is configured not to indent the children of the html and body tags, as well as any other tag that has more than 100 lines.
  • IDEA is also configured to recognize that some tags should have new lines before them (p, form, h1, h2, etc), but others should not, such as br.
  • Not shown here, but with these settings you can auto-format your entire HTML page and IDEA will follow all the rules here, including wrapping your text at the number of columns of your choosing.
  • Also not shown here, but IDEA has a "surround with" feature in Java (surround with try/catch, if/else, etc) that can be used for surrounding blocks with a tag. Very handy, just press ctrl-alt-t.
  • Also not shown here, but when you open a tag IDEA will automatically write out the closing tag. Or, if you have an open tag laying around, IDEA's auto-complete for the closing tag will prompt you for the valid tags you can close.

All of this is very nice. More so, IDEA plays very well with scripting languages, like JSP. That means that these features I outlined don't get in the way of dynamic HTML - IDEA is almost always aware of those situations and will step away such that you aren't presented with "false positives" in error reporting. Let's look at the code formatting features TextMate offers.

TextMate:
textmate3.png

Wow. It completes character pairs. Amazing.

Winner: IDEA, by a mile.

Now let's look at refactoring support. Suppose I need to rename an HTML file or CSS file. A good IDE will rename all the references to it. Similarly, if a reference is broken it should be identified and prompt you to fix it.

IDEA:
idea4.png

Notice that opensource.html doesn't exist, so IDEA highlights it as yellow (a warning) and gives me the option to create the file right there. Also, note that all errors (red underline) and warnings (yellow highlight) can jumped to by pressing F2 on your keyboard. This makes it really easy to quickly navigate to problems using only your keyboard. What does TextMate offer?

TextMate:
textmate4.png

Answer: nothing.

Winner: IDEA

Conclusion

I prefer using IDEA for HTML editing - even when my project has zero Java or any other programming involved. I tried out TextMate, SubEthaEdit, and other text editors and none of them had 1/10th of the power offered by IDEA's HTML editor. Clearly IDEA is the best.

... or is it? Are there any areas where IDEA looses to TextMate? Absolutely. It is much slower to start up, it has zero command line integration, and it is quite a bit more sluggish. The JavaScript support is nice but buggy as hell and now causes the startup time to take even longer.

But the point of this article isn't actually to have some inane debate about Java vs Rails or IDEA vs TextMate. It is to point out that these debates are absolutely retarded and are merely designed to hype up a bunch of mindless followers. Tool X may do A, B, and C better than tool Y, but tool Y might very well do D, E, and F better. Rather, disguised in this ridiculously slanted review is, I hope, a real review of some awesome features that I can't go without.

I hope that both the Java and Ruby communities can stop saying brainless statements like "Ruby is not Enterprise ready" or "I'm glad you're warming up to the idea of productivity" (as if I lived in some unproductive cave for the last 5 years) and start showing in very specific detail why Tool X makes my life so much better. Perhaps once we can do that, we can finally take the best of all these tools and come up with something that really is better than [fill in the blank].

March 22, 2006

Dumb comment of the day

From java.util.logging.LogRecord:

    public LogRecord(Level level, String msg) {
	// Make sure level isn't null, by calling random method.
	level.getClass();
	this.level = level;
	message = msg;
	// Assign a thread ID and a unique sequence number.
	synchronized (LogRecord.class) {
	    sequenceNumber = globalSequenceNumber++;
	    Integer id = (Integer)threadIds.get();
	    if (id == null) {
		id = new Integer(nextThreadId++);
		threadIds.set(id);
	    }
	    threadID = id.intValue();
	}
	millis = System.currentTimeMillis(); 
	needToInferCaller = true;
   }

Make sure level isn't null, by calling random method?! Why not use an assert? Or, if the concern is that asserts might be disabled, be explicit about the null check? Very odd.

JDK logging's lack of var args

Can someone explain to me why the JDK logging API didn't get a refresh to support var args in Java 5? Other APIs, such as the reflection APIs, were updated. Why didn't Sun update the Logger interface? Is there a backwards compatibility issue I'm missing?

March 21, 2006

MacBook: almost great

I love my new MacBook. It is now my primary development machine, even though it is still slightly slower than my AMD 64 ×2 4400 dual core PC. But it is fast enough, and the OS is just so much nicer.

The only real problem, besides the occasional glitch/freeze that seems to be related to Rosetta, is that the battery life absolutely sucks. I'm lucky if I get 2 hours if wireless is turned on and the screen brightness is high. Pretty sad. I hope it turns out to just be a software issue that can be patched later.

WebWork Flash Scope Support

I finally found a need for the "flash" scope that is so hyped with Ruby on Rails. Wondering how hard it would be to implement, I decided to just do it. I didn't add it to WebWork, since we're about to do a 2.2.2 release. Instead, I just added on to WebWork for my project. It couldn't have been easier:

  • Make a new result type flash that simply saves the action before redirecting
  • Make a new interceptor that can be applied to all actions and adds any flashed actions it finds to the stack

Result:

public class Flash extends Redirect {
    protected void doExecute(String finalLocation, ActionInvocation invocation) {
        // before we redirect, let's save the state in to the session
        Object action = invocation.getAction();
        Map session = invocation.getInvocationContext().getSession();
        session.put("__flash", action);

        super.doExecute(finalLocation, invocation);
    }
}

Interceptor:

public class FlashInterceptor implements Interceptor {
    public String intercept(ActionInvocation ai) throws Exception {
        Map session = ai.getInvocationContext().getSession();
        Object action = session.get("__flash");
        if (action != null) {
            session.remove("__flash");

            OgnlValueStack stack = ai.getStack();
            stack.push(action);
        }

        return ai.invoke();
    }
}

Now just make this both globally available to all your actions. Now instead of doing a chain or just not doing neat stuff like embedding multiple forms in a single page, just make your action's INPUT result be of type flash and point back to the complex page that hosts the form. The original form values and new validation errors will just magically be there.

Note: that was done in less than 15 lines of functional code. It is also a great example of why you should learn the in's and out's of whatever libraries or frameworks you work with.

March 14, 2006

The dangers of hosting

My new venture, Autoriginate, Inc, is exploring various product directions and distribution models. One of them is a hosted product. While I think that generally hosting is a great way to go, this article about Saleforce.com's recent problems does give me something to think about.

When you have a shipping product, customers that don't push it as hard won't see performance problems. When you have a hosted product, everyone sees them.

Anyone else have thoughts on the hosted model?

Sun: proving their stupidity once again

Sun is just so out of touch with Java users. Geert's recent question about annotation support in HotSwap is a perfect example.

Are annotations hot-swappable?:

I've been working on annotations support in RIFE for a few days, and now that I'm testing them in real projects I stumbled into what seems like a major downer.

(Via New RIFERS blogs entries from Geert Bevin.)

Users want to be able to make changes quickly. Sun can support it with HotSwap. In fact, Sun could, if they wanted, make HotSwap support complete for development work (it would be unsafe for production).

But instead, Sun pulls a bonehead move and takes a step backward. They introduce annotations, a perfect replacement for more verbose XML, but don't permit them to be changed quickly at runtime. Now XML is still the best option for rapid development, purely because frameworks like WebWork can reload the XML when they see the file has changed.

Sun: get with the program!

What can you do? Vote for the bug that would resolve this, and also provide feedback on their forums begging for them to shape up.