Follow-up to our Dev Brunch July 2010

A follow-up to our July 2010 Dev Brunch, summarizing the talks and providing bonus material.

Last Saturday, we held our Dev Brunch for July 2010. The setting of this brunch was unusual, as we didn’t brunch, but cooked spaghetti (to be exact: had spaghetti cooked while we ranted about different workplaces). We also didn’t start in the late morning, but in the early afternoon. Later on, a LAN computer game party was held in our office, limiting our time-frame a bit. Due to rainy weather, we stayed inside and discussed the topics listed below.

The Dev Brunch

If you want to know more about the meaning of the term “Dev Brunch” or how we implement it, have a look at the follow-up posting of the brunch in October 2009. We continue to allow presence over topics. Our topics for the brunch were:

  • Your own Java ResourceBundle implementation – Since Java 6, there is the new possibility to add your own ResourceBundle formats under the generic API using ResourceBundle.Control. We discussed several possible use cases and had an example case mocked up in source code. The API enables you to do what was impossible beforehands but isn’t as polished as it could be. Worth a closer look if you want to combine ResourceBundle with your i18n database, for example.
  • Thoughts on “Team Rooms” – Lately, there was a very good blog entry about team rooms and how they are introduced by Martin Fowler. The article is titled “The rise of the cattle office” and has some valid points. But nearly every attendee of the brunch likes working in a team room. We had a great discussion that can’t be summarized in a single sentence, but one advice: Mr. Fowler, please put up some nicer teaser image in your bliki!
  • Retrospective of the Java Forum Stuttgart 2010 – The Java Forum Stuttgart 2010 is a local conference dedicated to Java. It grew into a 1k+ developer’s meeting for southwest germany. You cannot avoid to meet former colleagues and chat non-stop in the pauses. The presentations are mostly very professional and worthwhile. We learnt a bit about long-term serialization issues (put a version in your XML namespace!), better JUnit (Rules are cool!), some Dependency Injection myths (though this presentation could have been snappier) and got introduced to Apache Hadoop (Map/Reduce at its best). Embedded Java still is the hell we remembered it to be. But the best presentation of the day clearly was Dr. Simon Wiest talking about Hudson and advanced techniques to speed up your build.

Retrospection of the brunch

The group of attendees was small again, with several firsttime guests. This helped the disgression factor a lot, we talked a lot about all kinds of topics that didn’t make it on the list above. The time and setup was a bit unusual, but the brunch itself was fun and insightful as always.

Non-trivial Custom Data in QActions

If you want to implement dynamic context menus with non-trivial custom data in your QActions, the Qt4 documentation is not very helpful. The article describes some solutions to this task.

Sometimes I get very frustrated with the online Qt4 documentation. Sure, the API docs are massive but for many parts they provide only very basic information. Unfortunately, many Qt books, too, often stop exactly at the point where it gets interesting.

One example for this are context menus. The API docs just show you how menus in general are created and how they are connected to the application: Basically, all menus are instances of QMenu which are filled with instances of QAction. QActions are used as representation of any kind of action than can be triggered from the GUI.

The standard method to connect QActions to the GUI controlling code is to use one of their signals, e.g. triggered(). This signal can be connected to a slot of your own class where you can then execute the corresponding action. This works fine as long as you have a limited set of actions that you all know at coding time. For example, a menu in your tool bar which contains actions Undo/Redo/Cut/Copy/Paste can be created very easily.

But there are use cases where you do not know in advance how many actions there will be in your menus. For example, in an application that provides a GUI for composing a complex data structure you may want to provide the user assisting context menus for adding new data parts depending on what parts already exist. Suddenly, you have to connect many actions to one slot and then you somehow have to know which QAction the user actually clicked.

Btw, let’s all recall the Command Pattern for a moment… ok, now on to some solutions.

Method 0 – QAction::setData: The QAction class provides method setData(), which can be used to store custom data in a QAction instance using QVariant as data wrapper. If you then use QMenu’s triggered signal, which gives you a pointer to the QAction that was clicked, you can extract your data from the QAction. I find this a little bit ugly since you have to wrap your data into QVariant which can get messy, if you want to provide more than one data element

Method 1 – Enhancing QAction::triggered(): By sub-classing QAction you can provide your own triggered() signal which you can enhance with all parameters you need in your slot.

class MyAction : public QAction
{
  Q_OBJECT
  public:
    MyAction(QString someActionInfo)
      : someActionInfo_(someActionInfo)
    {
      connect(this, SIGNAL(triggered()),
              this, SLOT(onTriggered()));
    }
  signals:
    void triggered(QString someActionInfo);
  private slots:
    void onTriggered() {
      emit triggered(someActionInfo_);
    }
  private:
    QString someActionInfo_;
};

This is nice and easy but limited to what data types can be transported via signal/slot parameters.

Method 2 – QSignalMapper: From the Qt4 docs on QSignalMapper:

This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to the object that sent the signal.

… which is basically the same as we did in method 1.

Method 3 – Separate domain specific action classes: By the time the context menu is created you add QActions to the menu using QMenu’s addAction methods. Then you create instances of separate Command-like classes (as in Command Pattern) and connect them with the QAction’s triggered() signal:

// Command-like custom action class. No GUI related stuff here!
class MySpecialAction : public QObject
{
  Q_OBJECT
  public:
    MySpecialAction(QObject* parent, <all necessary parameters to execute>);

  public slots:
    void execute();
  ...
};

// create context menu
QAction* specialAction =
  menu->addAction("Special Action Nr. 1");
MySpecialAction* mySpecialAction =
  new MySpecialAction(specialAction, ...);
connect(specialAction, SIGNAL(triggered()),
        mySpecialAction, SLOT(execute()));

As you can see, QAction specialAction is parent of mySpecialAction, thereby taking ownership of mySpecialAction. This is my preferred approach because it is the most flexible in terms of what custom data can be stored in the command. Furthermore, the part that contains the execution code – MySpecialAction – has nothing at all to do with GUI stuff and can easily be used in other parts of the system, e.g. non-GUI system interfaces.

How have you solved this problem?

Are programming books overrated?

A little insight gathered through feedback from an internship. Software development books are somewhat overrated as they can’t teach practice well.

In the last few weeks, we had an internship of a student that just finished academic high school (“Gymnasium”) and is looking forward to take up studies in computer science. He wanted to get in touch with the practical aspects of the career he is about to choose. The programming courses in school merely covered the basics of a programming language (Java) and some UML.

We prepared the student for the internship by feeding him several books we thought were appropriate for his level of knowledge. The books were a beginner’s book about Java (Head First Java), an introduction to unit testing (Pragmatic Unit Testing) and a foundation on clean code programming (Refactoring). Our student read them thoroughly and could make references to the chapters during pair programming sessions.

Retrospective on the books

But one feedback we got from him was that the books alone were nearly useless for his case. If there wouldn’t have been tutorial style pair programming coding sessions and several short lectures , he couldn’t grasp the deeper meaning of the book chapters he read (he suffered from the “blank slate blockade” several times). This came a bit as a surprise for us, as the student was very clever and really into it. It wasn’t the student, it was the books.

But you can’t blame it on “Refactoring”, for example, as this book is an all-time classic filled with really important knowledge. It has to be the medium itself, books are not the ideal source to learn about programming and software development.

Books are part of the academics

There is an old question in our profession. It revolves around if we are more like engineers or artists, craftsmen or scientists. In the core of this question is a uncertainty about the right model of education. Artists and craftsmen prefer more practical training, with apprentice/master relations and personal knowledge transfer. For engineers and scientists, literature and more standardized lectures are better suited. Academic knowledge is transferred during debate, not during exercises.

The duality of our profession

Projecting the feedback of our student onto this question, there seems to be a duality in our profession: Both (or all four if you want) approaches are needed to form a whole. You can’t learn the theory and expect to excel on the job. But pratical experience alone will not suffice to keep up with the pace of our profession. Good books are like afterburners here, you’ll be hurled forward by every page.

Conclusion

If it’s really true that we need to learn our profession both ways at once, pair programming (in the tour guide or backseat driver style) is an essential part of our qualification. And our current university curriculum fails to deliver this part. Students nowadays can team up to program together on an assignment, but that’s not learning from a master (unless one in the team has distinctly more experience than everybody else and is able to transfer it). So I vote to bring more craftsmanship to the academic education, as the books alone won’t cut it.

Your opinion?

What’s your opinion on this topic? Drop us a line about your thoughts.

An Oracle story: Null, empty or what?

One big argument for relational databases is SQL which as a standard minimizes the effort needed to switch your app between different DBMSes. This comes particularily handy when using in-memory databases (like HSQL or H2) for development and a “big” one (like PostgreSQL, MySQL, DB2, MS SqlServer or Oracle) in production. The pity is that there are subtle differences with regard to the interpretation of the SQL-standard when it comes to databases from different vendors.

Oracle is particularily picky and offers quite some interesting behaviours: Most databases (all that I know well) treat null and empty as different values when it comes to strings. So it is perfectly valid to store an empty string in a not-null column and retrieving the string from the column yields an empty string. Not so with Oracle 10g! Inserting null and retrieving the value yields unsurprisingly null, even using Oracle. Inserting an empty string and retrieving the value leaves you with null, too! Oracle does not differentiate between empty strings and null values like a Java developer would expect. In our environment this has led to surprised developers and locally unreproducible bug which clearly exist in production a couple of times.

[rant]Oracle has great features for big installations and enterprises that can afford the support, maintenance and hardware of a serious Oracle DBMS installation. But IMHO it is a shame that such a big player in the market does not really care about the shortcomings of their flagship product and standards in general (Oracle 10g only supports SQL92 entry level!). Oracle, please fix such issues and help us developers to get rid of special casing for your database product![/rant]

The lesson to be learnt here is that you need a clone of the production database for your integration tests or acceptance tests to be really effective. Quite some bugs have slipped into production because of subtle differences in behaviour of our inhouse databases and the ones in production at the customer site.

Grails pitfall: Proxies and inheritance

When using inheritance in a lazy fetched association, proxies are a common pitfall in Grails.

Problem

You have a domain class hierarchy and want to use the classes in an association. You typically use the base class in a hasMany:

class Domain {
  static hasMany = [others:BaseClass]
}

Dependent on the actual class in the set others you want to call a different method:

public doSomething(domain) {
  domain.others.each {doThis(it)}
}

public doThis(ChildClassOne c) {}

public doThis(ChildClassTwo c) {}
...

Here the proxy mechanism of Hibernate (and Grails) causes a MethodMissingException to be thrown because the proxies are instances of the base class and not the actual child ones.
One way would be to activate eager fetching or you could use…

Solution: A dynamic visitor

Declare a visit method in the base class which takes a closure

def visit(Closure c) {
return c(this)
}

and make the dispatch in a method for the base class:

public doThis(BaseClass c) {
  return c.visit {doThis(it)}
}

Open Source Love Day June 2010

Our Open Source Love Day for June 2010 brought love for Hudson (especially the Campfire Plugin), Launch4j and RXTX. Everything went smooth and we were soaked with sweat due to massive sunshine.

Last wednesday, we held our Open Source Love Day for June 2010. This one was productive despite the heat that had us sweating the whole day long (as a sidenote: it got even warmer the days afterwards). Some features were finished and will help at least us in our projects. We still look forward for the right way to release them. Another release was even more problematic, you will read about it below.

The Open Source Love Day

We introduced a monthly Open Source Love Day (OSLD) to show our appreciation to the Open Source software ecosystem and to donate back. We heavily rely on Open Source software for our projects. We would be honored if you find our contributions useful. Check out our first OSLD blog posting for details on the event itself.

On this OSLD, we accomplished the following tasks:

  • Launch4j is a java application launcher for Windows, handling all the stuff a startup script would do, too. At the last OSLD, we added the ability to restart the application in case of a crash or other unplanned exit. To utilize this feature for automatic update routines, we needed to add the additional feature of starting another command instead of the original one. If the program fills a special file with the command needed, Launch4j will execute it after the program’s exit. This patch builds onto the previous patch and we are still investigating how to publish this functionality without breaking backward compatibility. We are looking forward to release it on the next OSLD.
  • We use RXTX to perform the serial (RS232) communication on all our java projects. We worked on an issue with serial converters over the course of several OSLDs now and released the patch to the issue tracker of RXTX after a longterm stability test. See the reworked patch for issue #144. There is another issue with the flush() method that seems to affect not only virtual RS232 ports that we currently investigate. But we aren’t yet able to come up with a complete issue description or a fix, so this will be suspended until the next OSLD.
  • We have written the Campfire Hudson Plugin as part of previous OSLDs. When issues emerged, we got patches from the community here. Thank you guys! We included the changes to the code and prepared a new release, when maven failed. This is not an issue, except when it fails repeatedly and messes up the workspace and the repository. After a long time of helpless fiddling with the parameters, we decided to start over and increase the version number to 2.1 (instead of 1.2). All of a sudden, everything worked out fine. Maven is a mysterious beast.
  • The initial work for a New Hudson Plugin was made. One tradition of the OSLD has always been to scratch our own itches. While there are many useful hudson plugins, we have the immediate need for another one that doesn’t exist yet. Without going into details here (we save this for the next OSLD), we produced a proof of concept and a first iteration of the code. Stay tuned for details on the next OSLD.

What were our lessons learnt today?

  • If you don’t succeed with maven’s automatic processes, do not try to sort out things manually. You’ll just end up with a gigantic mess that won’t work either way. The best way to deal with maven failures is to revert everything and try again with different parameters.
  • The best approach to develop hudson plugins is to adapt the old “monkey see, monkey do” process. There are so many plugins already, chances are good your immediate question was already answered somewhere. Just check the found solution for accidental complexity. Sometimes, the first solution isn’t the easiest.
  • When dealing with the legacy Win32 API, combined knowledge scraping is king. We had discussions throughout the day that only consisted of little parts of recollections about knowledge that seemed long forgotten. But finally, we put the pieces together and solved the problem. It should be called teamthink, i guess.

Retrospective on the OSLD

The weather at this OSLD was way too hot to operate at normal speed. But we got some nice results and a cliffhanger for the next OSLD. We left soaked with sweat but happy that evening.

Add flair to your code: Code Squiggles

Introduction to Code Squiggles, a coding style that improves the readability of your java code.

Wrought Iron by quadriremeFor several months now, I’m experimenting with a programming style that you might want to call “syntax aware programming”. Every coding step starts with the question “what do I want to achieve and how do I want to write it down?”. Then I proceed to write it down in this perfect manner, mostly some english sentence, and try to incrementally convert the syntax into something the java compiler stops complaining about. There’s a lot to be learnt about API design, naming and creative syntax usage this way. One thing I’ve discovered along the way are Code Squiggles.

Introduction to Code Squiggles

Code squiggles are little methods that contain no functionality, other than directly returning the single given parameter. Their purpose is to make the code more fluently readable by casual readers. Calling these methods is absolutely optional, as they offer no behaviour at runtime. But by bloating your code with these method calls, you lower the amount of syntax rules and conventions the reader has to know before being able to understand the code. The process of adding the method calls feels like adding “happy little squiggles” (I certainly miss Bob Ross!) to your code.

Adding Code Squiggles by example

Let me give you a full example how Code Squiggles can turn your boring old java code into something even non-programming readers can grasp without problems. Note that the process of transforming the code isn’t the process I initially described, but the way to deal with existing code.

The initial code fragment looks like this:

assertTrue(filesDirectory.getChild("0.png").isFile());

As you can see, it’s an assertion line of an unit test. We improve the readability by extracting the intent of the assertion into the called method name (it’s a normal “extract method” refactoring):

assertFileExists("0.png", filesDirectory);

Now is the time to add the first Code Squiggle:

assertFileExists("0.png", in(filesDirectory));

You’ve noticed the difference? It’s just the word “in”, but it improves the semantics of the second parameter. As I promised, Code Squiggles are methods without any functionality worth talking about:

protected VirtualFile in(VirtualFile filesDirectory) {
    return filesDirectory;
}

The method takes a parameter and returns it. The real “functionality” of this method lies within its name. Everything else is only necessary to overcome (or overcode) java’s shortcoming of advanced syntax definition measures.

That’s all about Code Squiggles. But it doesn’t stop here. Let’s improve the example to its final shape, when we add two squiggles:

assertFile(withName("0.png"), existsIn(filesDirectory));

Read this line out loud! And notice the subtle change in the assertion method’s name. It begins to deminish clarity without the Code Squiggles. That’s when your API begins to depend on them. But it’s still perfectly valid java code if you just omit them.

The conceptual origin of Code Squiggles clearly comes from the behaviour driven development (BDD) style of writing tests and the ScalaTest Matchers. So I can’t claim much originality or cleverness myself here. But Code Squiggles, despite this initial example, aren’t limited to test code.

Adding inline documentation with Code Squiggles

Remember the last time you needed to integrate an horrible third-party API? Probably, there was a method with seven or eight parameters and all of them were primitive ints. No matter how often you called this method, you couldn’t remember the order of these ints. That’s when Code Squiggles might help you a bit.

This is the signature of a fairly complex method:

protected int performCalculation(int value, int lowerLimit, int upperLimit, int offset) { ...

Therefore, your call isn’t very self-explanatory:

int result = performCalculation(10, 2, 23, 13);

But it might be a lot more understandable when you add some squiggles:

int result = performCalculation(value(10), lowerLimit(2), upperLimit(23), offset(13));

I won’t spell out the squiggle implementations, as they should be straight-forward. Note that the java compiler doesn’t catch up here. You can easily swap the squiggles around to obfuscate your code. All you got is read-time safety. If you want compile-time safety, you need to replace the primitives with types and probably pay for some rounds of beer for the third-party API developers to include your changes or write an adapter (“corruption layer” is my preferred term here).

Regular use of Code Squiggles

If you want to use squiggles a lot, you might think about collecting them in a dedicated class. Design them to be static and generic, and you can use them easily with static imports:

public static <T> T existsIn(T instance) {
    return instance;
}

But remember that there are reserved keywords in java that might hamper you a bit.

Conclusion

Code Squiggles are useless bloat to your code unless you value read-time safety or casual readability. They can tidy up your code to a point where method or even class names are affected to form a block of code where you only have to replace the funnier chars with blanks to obtain a paragraph of plain written english anybody can read and understand.

What are your ideas towards Code Squiggles? Have you used them on your code? Mind to share the result?

Code squiggles are little methods that contain no functionality, other than directly returning the single given parameter. Their purpose is to make the code more fluently readable by casual readers.

Follow-up to our Dev Brunch June 2010

A follow-up to our June 2010 Dev Brunch, summarizing the talks and providing bonus material.

Today, we held our Dev Brunch for June 2010. It was a small group of developers this time, too, as some of our usual attendees turned into parents and can’t wrap their head around anything but their kid. First things first. The good news is that today, we had a new attendee that joined our group after reading our blog articles. This time, the communication beforehands went right. Our office roof garden once again served as a great hangout place as we discussed the topics listed below.

The Dev Brunch

If you want to know more about the meaning of the term “Dev Brunch” or how we implement it, have a look at the follow-up posting of the brunch in October 2009. We continue to allow presence over topics. Our topics for the brunch were:

Google Web Toolkit, internationalization (i18n) and customer customizable text – This wasn’t a presentation, but more a discussion of different options around the fact that GWT i18n works best (and smoothest) when baked into the compiled binary. If you have a customer that wants to change every textual aspect of your projects, chances are that performance will suffer. If your job is to provide a flexible, yet powerful base product as a starting point for individual customer solutions, there’s a huge tradeoff to make here.

First-hand experience of Yoxos 5 Beta – The EclipseSource Yoxos Launcher is a cool new product that helps to keep the management overhead in setting up your IDE (eclipse as you might already have concluded) minimal. It’s a little program that downloads and sets up everything you specified in your launch profile and starts a ready-to-use eclipse instance. You can share the launch profile and keep it in sync so everybody in your group can be sure to work with the complete official setup. This talk was about a real-world use case, the unique features and the areas that still need a bit more work. Remember that it’s beta.

A book chapter review of The Passionate Programmer – The book is the second revision of the former “My Job Went To India…” book from the Pragmatic Bookshelf. It contains insights and advices on making a living in software development. It also has a focus on enterprise career planning in the IT with the background threat of outsourcing or even offshoring. Two chapters were discussed in more detail: That you should keep a map of your technology skills up-to-date (like this example) and that you really should seek to make friends with software maintainance work, as it probably will be the actual job that pays your bills.

Introduction to Code Squiggles – One of the results of a experimental quest to improve the coding style in Java are Code Squiggles. There will be a full-detail blog entry about them shortly, so this is just a teaser. Code Squiggles don’t add functionality or safety to your code, but seek to improve the readability of your code. The ultimate goal is to have your program written down in plain english with a few funny letters in between. Basically, they are intentional bloat to help the casual code reader.

As usual, the topics ranged from first-hand experiences and impressions to literature reviews and research. For additional information provided by the talk authors, check out the comment section (or leave a comment to request further content). Comments and resources might be in german language.

Retrospection of the brunch

Today, we started by giving a quick introduction of ourselves to each other. Being a small group, we digressed a lot more as time wasn’t that much of an issue. The list above is in no way a summary of all the sidenotes and topics we really talked about, it’s just the main topics that served as a starting point for insightful developer chatter. The brunch keeps getting better.

The C++ Shoot-yourself-in-the-Foot of the Week

I think we can all agree that C++, compared to other languages, provides quite a number of possibilities to screw up. Everybody working with the language at some point probably had problems with e.g. its exception system, operator overloading or automatic type conversions – to name just a few of the darker corners.

There are also many mitigation strategies which all come down to ban certain aspects of the language and/or define strict code conventions. If you follow Google’s style guide, for example, you cannot use exceptions and you are restricted to a very small set of boost libs.

But developers – being humans – often find creative and surprising ways to thwart every good intentions. In an external project the following conventions are in place:

  • Use const wherever you possibly can
  • Use boost::shared_ptr wherever it makes sense.
  • Define typedefs to shared_ptrs  in order to make code more readable.
  • typedefs to shared_ptrs are to be defined like this:
typedef boost::shared_ptr&lt;MySuperDuperClass&gt; MySuperDuperClassPtr;
  • typedefs to shared const pointers are to be defined like this:
typedef boost::shared_ptr&lt;const MySuperDuperClass&gt; MySuperDuperClassCPtr;

As you can see, postfixes Ptr and CPtr are the markers for normal shared_ptrs and constant shared_ptrs.

Last week, a compile error about some const to non-const conversion made me nearly pull my hair out. The types of variables that were involved all had the CPtr postfix but still the code didn’t compile. After a little digging I found that one of the typedefs involved was like this:

typedef boost::shared_ptr&lt;  MySuperDuperClass&gt; MySuperDuperClassCPtr;

Somebody just deleted the const modifier in front of MySuperDuperClass but left the name with the CPtr untouched. And because non-const to const conversions are allowed this was not detected for a couple of weeks. Nice going!

Any suggestions for a decent style checker for c++? Thanks in advance 😉

Looking left and right will improve you as a developer

After initial encounters with computers and programming I pretty much settled with Java as my preferred Language and especially platform. Occasional adventures to C/C++ or other languages and tools do happen but not on a day to day basis. We are mostly a Java shop so this seems natural. However, I strongly suggest looking left and right and trying new stuff, be it a programming language, an operating system, an IDE or a programming framework. Similarily to travelling around in the real world™ it will widen your views on your daily work and give you new ideas on how to improve it. You will try to adapt new good stuff from elsewhere and on the other hand appreciate nice aspects of your current environment more.

Let me give some examples to support my point and motivate adventures outside your home turf. I have been playing around with Scala and therefore functional programming in the past months. One major benefit of these experiments was my new appreciation for immutable types and side effect free code. You can carry them over to many programming environments including Java often making your code easier to test and less error prone. Object-oriented programming (OOP) relies heavily on objects with state and side effects but there are many places where immutability reduces tracking effort of objects and their state. A nice example in Java is the Joda Time library with provides immutable DateTime-classes in contrast to java.util.Date et al. Null-Handling in Scala using the Option-Type seems so interesting that some people try to carry it over to Java as an alternative to Null-Objects or null checks. The rich collection classes and implicit conversions in Scala may encourage you write own utility classes for Java collections, nice wrappers or use alternative collection frameworks to make your life easier. In general, I find wrapping a nice, standard OO-technique often underused outside of frameworks.

You do not always have to stray that far. Some frameworks like Fest and EasyMock show nice usages of fluent interfaces. Why not use this technique in own code? I found them especially useful for implementing builders for complex or highly configurable objects. Fluent interfaces can make your code look a lot like natural language resulting in expressive and highly readably code.

Using Mac OS X with Spotlight™ and TimeMachine™ may make you look for similiar features on your Linux Box (e.g. gDeskbar and BackInTime) or Windows (depending on version available through third party software or built-in). Using the multiple deskops of Linux (or another OS with an X11-Window system) may motivate you to try them in your other working environments (they suck on OS X, though).

Trying different IDEs may increase your effectiveness depending on the language and frameworks used. Grails support may be better in IntelliJ whereas you may like Eclipse more for plain J2SE projects. Sometimes you will find some cool feature in one IDE you were missing before. I encourage you to go back to your environment and look for the same or similar features. Often you will find them in many advanced IDEs.

Without seeing what is possible you may never miss it. But beware thinking everything new is automatically better. The grass is always greener on the other side. Try to reflect on the things you learn and encounter. Take the good parts to improve existing stuff whenever sensible. But also do not fear to move on if it is time.

For me and my colleagues this wandering around in this rich software development world has proven very valuable to continually improve our style and increase our productivity. These adventures in foreign waters coupled with reading books, dev brunches and attending talks on and offline keeps our skills fresh and improving. Sometimes it may even lead to own ideas, APIs and tools.