Archive for August, 2005

A message to Sun engineers: Please stop making my code ugly

Tuesday, August 30th, 2005

Java has had the concept of beans and getters and setters for a long time. I thought we had all agreed that they work and clearly show intent. I felt annoyed when I saw the java.util.regex package appear in Java 1.4 with methods like matcher(CharSequence) and group(int), when they should have started respectively with create and get. I didn’t like so much the new Java 5 util.concurrent methods Executors.callable(Runnable), which should be prefixed with get or create.

I just now came across the new ProcessBuilder class in Java 5, with methods like redirectErrorStream(boolean) and environment() which should be a setter and a getter, respectively.

It’s harder and less pleasant for me to read my own code when using these classes. I hope Sun engineers will stop knowingly making Java code uglier in future releases.

The JVM feature that would improve my productivity the most: unlimited Hot Swap

Friday, August 26th, 2005

I develop IntelliJ IDEA plugins and web applications. I must see “Can’t reload classes: add method not supported” 20 times per day. Then I shut down, wait 2 minutes for IDEA or Tomcat to start in debug mode, and continue debugging. I think I could get twice as much done in a day if I didn’t have to do this. I know there’s a bug in the Sun database but I can’t find it. The Sun issue report for this problem is 4910812.

Are you a slave to hot swap? Do you avoid renaming, extracting, or changing modifiers of methods so you can reload the classes? How do you get around it?

Looking for a Usenet (NNTP) Reader

Sunday, August 14th, 2005

I’m looking for a Usenet newsreader like this:

  • Show posts from a set of newsgroups in one list
  • Download all new posts immediately, so I don’t have to wait half a second to view each message
  • Show threads in one big nested page, like web forums
  • Show new message count in the dock, like Mail or Thunderbird do for mail messages

I’ve never used a newsreader that does all of these things, and I’ve never even seen one that does a few of them. Have you? You should leave a comment below if you know of a reader that I might like.

A huge gotcha with Javascript closures and loops

Monday, August 8th, 2005

Javascript function closures probably don’t work the way you think they do.

UPDATE: I have modified my first example code to make the problem clearer.

My problem

I was writing some code today to dynamically insert a large number of HTML elements into the DOM, and give each of them a unique onclick function. My code looked vaguely like this:

[...]
var array = ...
for (int i = 0; i < length; i++) {
  var object = this.createNode()
  var picker = this
  var x = array[i]
  object.onclick = function() {
    picker.select(x)
  }
}

I needed to created a new function for each onclick because each one called select with a different parameter. However, I came across a problem that didn’t make any sense - when I clicked any one of the generated elements on the page, the last onclick function I had created was called. That is, if length was 31, then no matter which element I clicked, select was called with the 31st object in the array.

After hours of debugging and downloading Venkman and searching for information about Javascript closures, I finally found a discussion on the newsgroup comp.lang.javascript, in which Dom Leonard said:

Browser independant code *may not* rely on obtaining a different,
unjoined function object for *any* function declared inside another
function, whether this be because of function declaration or expression
within a loop, across calls to the containing function, or whether the
function be annonomous or named. ECMA 262 both *allows* them to be
different in all cases and *allows* them to share all external
properties (including prototype and user defined properties) in all
cases (because of join operations retaining differences in the scope
chain) and in some cases even *allows* them to be the same function
object without joining.

This was my problem - the browser appeared to be “joining” my function declarations into a single object, instead of creating a new function object for each iteration of the loop.

I’ll provide you with a solution in a minute, but first I have a fun demo for you. What do you think the following code will do?:

<html>
<head>
  <script type="text/javascript">
  function loadme() {
    var arr = ["a", "b", "c"];
    var fs = [];
    for (var i in arr) {
      var x = arr[i];
      var f = function() { alert(x) };
      f();
      fs.push(f);
    }
    for (var j in fs) {
      fs[j]();
    }
  }
  </script>
</head>
<body onload="loadme()"> 

</body>
</html>

If you think it will show alerts “a” then “b” then “c” then “a” “b” “c” again, you’re wrong. In Safari and Firefox, it produces “a”, “b”, “c”, “c”, “c”, “c”. Even though we create the function() in a loop, and x is stored as part of that function’s closure, the same function is used each time, and the closure information is replaced during each iteration.

A solution

I currently use a workaround for this behavior, as described in the comp.lang.javascript discussion. The following code works correctly, producing “a” “b” “c” twice:


<html>
<head>
  <script type="text/javascript">
  function createFunction(x) {
    return function() { alert(x); }
  }
  function loadme() {
    var arr = ["a", "b", "c"];
    var fs = [];
    for (var i in arr) {
      var x = arr[i];
//      var f = function() {
//        alert(x);
//      }
      var f = createFunction(x);
      f();
      fs.push(f);
    }
    for (var j in fs) {
      fs[j]();
    }
  }
  </script>
</head>
<body onload="loadme()"> 

</body>
</html>

However, even this code is not guaranteed to work correctly according to the ECMA spec. I don’t know what is the correct way to do this, according to the spec. If you think you’ve figured it out, please post a comment below.

Tal Liron working on AIM server application using joscar

Monday, August 8th, 2005

Tal Liron is working on an AOL Instant Messenger server using joscar. It’s a very cool project, involving bridging many IM protocols. I’m excited because this will be the first real AIM server implementation using joscar. I’ll post a link here when he has a website and more information ready.