Ben and I attended a session on the state of Ruby Tooling. Again, since this was a presentation from Sun employees, they admitted up front that it was really a NetBeans presentation. Still, they did a good job of identifying other alternatives so I won’t give them too hard a time.
Overall, I am probably lucky to be still conscious. I tried really hard to follow the details of what they are doing, but these guys were the sort of people that rockets scientists say ‘wow, those guys are geeks’. So, let me try to explain why.
The Code Completion Issue
Ruby is a dynamic language, so compared to static languages like Java it is pretty hard to work out what methods are available since you can’t use the static typing. So, the easy answer is that you start with just plain string matching. If you type ‘file.o’ and try to code complete the IDE will find any method that starts with ‘o’ – everywhere (Ruby, gems, your code). OK, this falls down pretty quickly since the results will overwhelm you. So, these guys then started to add more intelligence to the searching to narrow down appropriate results. Interestingly, they used Lucene to do this.
The IDE uses a number of approaches to apply weighting to results so that the code completion is returning fuzzy results in the best order it can determine. In some cases there are ‘exact’ matches as well as ‘fuzzy’ matches. The methods they use to weight are quite frankly berserk. For instance, to help work out the type of an argument (they are all of type Object until execution) they look for instances where the method is called from and inspect the types of the objects that are passed in. They can then determine the common methods on the different object types to try to hint the most likely object types. Riiiiight. That was just one of half a dozen techniques they are using, so safe to say that the fuzzy matching is quite good and will likely get better over time.
It is probably worth noting a couple of special cases to the above. For common Rails librarys like ActionController (but they didn’t mention ActievRecord!), they are documenting methods and return types and if they determine that you are using one of these types they will provide exact matches. In addition, they are supporting an annotation standard where if you use the right tags (similar to JavaDoc) in your method headers then the IDE can use this to display the valid methods. This is a little tricky since the implementation is going to win over the documentation every time so if the documentation is wrong it could lead you astray.
NetBeans and most of the alternatives (command line, RadRails/RDT, even TextMate) have debugging. Apparently there is a ‘slow’ and a ‘fast’ debugging library and depending on the IDE it might have used one or both. There is a lot of work going into the debug-commons project trying to create a single, fast debug library that everyone can use so over time all IDEs should have fast debugging. For now, I don’t think it is a big issue so we can pretty much mark off debugging as being available.
This is something that all the vendors/projects are scrambling to get to. Now that debugging and code completion are mostly done, they are moving on to refactoring. As per the above discussion, refactoring also poses some pretty interesting difficulties. Despite this, the NetBeans guys think they have a way to make method renaming possible (they already have the trivial case of local variable renaming). We also spoke to an Aptana guy in the JavaOne Pavilion who reassured us that the project was still live and that they are hoping to soon release refactoring support. I don’t have any details on what that might be, but it is reassuring to see that the project is still alive for all those Eclipse fans out there. Interestingly I asked him about code completion for ActiveRecord and he suggested that they would be using information in Migrations to determine the attributes rather than going to the database directly.
In summary, NetBeans has debugging, decent code completion and very little refactoring. I would expect to see better refactoring in the near future, probably by the end of the year. Even still, these functions in Ruby are always going to be ‘fuzzy’ compared to similar functionality in Java so there is going to be some adjustment by developers to get used to the new approach.