Monday, June 30, 2008

Singleton Methods

Ruby has a neat feature called Singleton Methods. The idea behind them is that you can define a method on an instance of an object, and that method only exists for that instance. Sounds pretty crazy the first time you learn about it, but it can prove quite powerful. This feature only makes sense in conjunction with duck typing (which I would like to dedicate another post about at some point). Don't expect a JSR for Singleton Methods for Java any time soon! Actually, you can do something similar using an anonymous class, but it would be rather hard to invoke, and you would have to define the method at the point of creation.

How could Singleton Methods possibly be useful? Well, my personal favorite is for unit tests. I prefer testing with actual classes, but sometimes that is not feasible. The object in question may not be built yet. It may be a legacy object that you don't want to touch because there aren't all that many tests for it, and it would just be easier to pretend that you have an instance of it. Perhaps the most likely scenario is that you are using a framework, and it is just plain annoying or infeasible to construct the real version of the object in question. Sockets are a prime candidate for this exact situation. Whatever the reason, you want to mock an object. What do you do in Java? You either construct an anonymous class, or you define a mock class which extends the object in question (or implements the required interface), and voila!

Except... anonymous classes are rather cumbersome, and an actual mock class separates your mock logic with the test that requires it. You could of course have a general purpose mock that is used everywhere, but you will have to go back and forth between the mock definition and your test class definition whenever you are developing tests that use the mock.

In comes Singleton Methods to the rescue! Your method only connects, and then does some extra work once it is connected, so you just need to mock the connect method. The following code would accomplish this goal:

mock = Object.new
def mock.connect()
end
invoke_my_method_with mock
# assert some conditions

Then, you should have a test in case the connect fails, right? Your object needs to do some other logic when the connection doesn't actually connect! So, the next test mocks the object differently:

mock = Object.new
def mock.connect()
raise "Some exception"
end
invoke_my_method_with mock
# assert some other conditions

Because of duck typing, your method doesn't know that it didn't get an actual Socket, but you were able to keep the mock logic near the test logic (in a clean and concise manner), which makes it a lot clearer what the test is testing.

Making mocking easier is nice, but ever since I learned Singleton Methods, I have been itching to use it in another way. Let's say we have an entity in our system that has a set of actions possible. My favorite case is a character in a game. There are many possible actions, but our character is only able to use a few of these actions. He can kick, but he can't punch. Each command could be a different Singleton Method! Now, whenever the character wants to punch, just invoke punch with the actual character instance. Of course, this means you have to be prepared that the character can't ACTUALLY punch, so you must catch a method missing error and inform the character that it tried to do an action it didn't know how to do (or perhaps didn't even exist). I don't know how this type of design would actually pan out, but it sure seems like the perfect fit for the feature.

I bet there are other good uses for Singleton Methods, so don't let these ideas limit the possibilities!

Thursday, June 26, 2008

Thoughts on Groovy

So I have been working with Groovy for the last few weeks on a for fun project at home. Nothing special, just a game... one that will probably never see the light of day, but I will nonetheless have fun with it for a while. I am a bit disappointed with Groovy, probably because I came at it having first learned Ruby. Groovy is very heavily influenced from Ruby, but not quite enough in my opinion.

Before I get into some issues I have with it, I guess I should note that it isn't ALL bad. Namely, they did a great job of making (mostly) seamless Java and Groovy integration possible... in BOTH directions. This is the 1 thing I wish JRuby would borrow from Groovy. What is the problem you ask? Well, with Groovy, you compile down to classes, and the resulting class is more or less exactly how you would expect it to work. That is, you can construct the object from Java directly, then call methods directly on it, exactly as you defined in your Groovy code. If you specified types, you will have access to those type declarations from Java. This is really good if you have an existing code base you want to integrate with. If you are starting an application from scratch with no dependencies, well, you might as well just stick with JRuby or Ruby (or whatever inferior language you like), since you can control whether integrating with your language from the Java end is a big deal. I played a TINY bit with Rhino, and they seem to have a similar type if integration possible, but Groovy seemed a lot cleaner... with Rhino you have to compile the class to a given object or interface... so the code itself doesn't really have a definition of the type in this case. Seemed like a bit of a hack to me, but if you are primarily using it from the JavaScript side, it is really a non-issue. Oh, and I decompiled the results of all 3 of these languages (Rhino, JRuby and Groovy), and Groovy seemed to add the lease baggage in the code, but it still had baggage.

Also... if you are a big fan of static typing, then Groovy will be a good transition to dynamic typing because you can fall back on static typing whenever you want. Personally, I see no reason to, but I am one who loves dynamic typing.

Now some bad things. Perhaps as a direct consequence of the apparent design goal to integrate seamlessly in both directions with Java, the language feels very... inconsistent. They TRY to do things in a nice dynamic way, but then fall short in some cases that I think Ruby shines in. This leading to my biggest gripe... the distinction between fields and methods. If you are going to support fields of varying scope, you essentially can't have the kind of clean design you have in Ruby. What do I mean by this? Well, let's look at an example.

In Ruby, if you have a property named "property" then you would define it as such:

attr_accessor :property

Which is equivalent to:

def property()
@property
end

def property=(value)
@property = value
end

So what is going on here? Well... we still have the distinction of fields and methods, but in Ruby, your fields are ALWAYS private. You can't make them public, so when you call a method, it will never be ambiguous with accessing a field. This means, invoking a method with no arguments, you can just drop the parenthesis because they are redundant. In fact, you can even drop them when there ARE arguments, as long as it doesn't make it ambiguous in conjunction with other method calls or whatever. I think this makes Ruby as clean as it is, and makes it really look like you are reading English... almost.

What about Groovy though? Well, they support a similar paradigm. Defining the same property is 1 line as well, but it looks like this:

def property

And it is essentially equivalent to creating getProperty() and setProperty(value). BUT! The consequence of seamless integration with Java means you can't drop the parenthesis in every method case. They too support dropping them when there are arguments, and it doesn't make it ambiguous, except when there are no arguments and it isn't a getter. Thus, in Ruby you could have "stream.close" but in Groovy it would have to be "stream.close()". This may seem minor, but every time I have to add those parens in Groovy, I'm reminded that Ruby's grammar feels so much more internally consistent.

I guess I wrote a lot about that, but for some reason that minor detail really irks me. Before I just end with only a single gripe, I better add a couple more for good measure. I haven't tried nested classes in Ruby yet (though I've read they are possible), but Groovy definitely doesn't support them, at least not now. I think this is something they will eventually get to, but as it stands, this is a major limitation. This seriously cuts short the "seamless integration" with Java that I feel is one of the significant strengths of Groovy. Not much more I can say about that, but maybe it's also because it is getting late and I am tired.

One more issue? Null. Groovy tried so hard to be like Ruby, but they missed yet another thing that I really like about Ruby. In Ruby, nil (Java and Groovy's null) is an object, just like any other object. What does this mean? Well, null pointer exceptions... no such thing. Instead they become a method missing error. This was a very cool concept to me the first time I saw it. I'm not sure if it allows significantly more concise code, but it does seem to pretty up the code, at least to me. A list of method calls as conditionals is a lot easier for me to parse than a mix of == and method conditionals. Visually, calling methods makes each condition a single entity, unlike with an == or != conditional. For example:

if connection != null && !connection.is_connected

vs

if !connection.nil? && !connection.connected?

Which brings me to another point that I won't go into too much details... but being able to add question marks and exclamation points to my method names has got me wishing I could do it in every language. Beyond cutting a couple characters from the method length, they allow you to add meta info about the method that is visible at a glance... such as question mark for asking a boolean question, and exclamation for indicating state will be changed (which are essentially the Ruby standards for their usage).

Ok, I have ranted enough. I haven't proofread this, because it is late. If anyone happens to read this, just enjoy or hate it as it is.

Mike

Monday, June 23, 2008

A JRuby Swing Library

Well, I haven't really posted anything yet, mostly because there is always something else to do. So, in an effort to actually start writing something, I have decided to post a little Ruby "library" I wrote a while ago. I put in the sarcastic quotes because it's quite a tiny library, if you can even call it that, but I think it has potential to be quite useful. I recently ported it to groovy for another personal project, and maybe I will post that next.

At any rate, before I list the code, I just wanted to say what its purpose is. Call me crazy (I probably am), but I like Java's Swing. Why? Well, it's portable in the sense that Java is portable... that is, you can easily install Java anwhere and thus have Swing at your fingertips... you can't really say that for most other UI libraries I have used (admittedly a small list). Either your window library of choice is X platform only (I'm looking at you Microsoft), or is just not nearly as pervasive as Java. Swing also does an OK job of looking decent, in my non-graphical-arts-critical eye (so take that with a grain of salt), and it can mostly look like your native platform with a special toggling (somewhere buried in the API that I end up always looking up, even though it is 1 or 2 lines of code).

So, with the good comes bad. I'm sure you can site many other bad things that I just don't have the experience or interest to point out, but the leading problem I am aware of, both in experience writing Swing GUIs and in reading other people mention the problem, is that it is an inherently tree structure being expressed in a non-tree syntax. The solution? XML! Well, there are many other options besides XML that provide a tree structure and don't make you want to gouge your eyes out, but XML happens to be pretty easy to parse in that most languages have a pre-packaged XML library. Thus, XML! Besides, XML is a lowest common denominator, everyone basically understands it, right? Isn't that what the XML enthusiasts try to shove down our throats?

Thus SwingXML was born, my tiny "library" that will take an XML definition, and load it into memory as a Swing component tree. Beyond representing the components in their inherent tree structure, it has the added benefit of separating your view definition from your view logic. In the groovy version I added a feature that I have not yet added to the Ruby version.

Without further ado:

require "java"
require "rexml/document"

class SwingXml
def initialize(xml)
document = REXML::Document.new(xml)
@widget_hash = {}
@widget = handle document.root, nil
end

attr_reader :widget

def [](widget_symbol)
@widget_hash[widget_symbol.to_sym]
end

private
def handle(element, parent)
raise ArgumentError, "Element #{element.name} does not have an sxmlId!" unless element.attributes.has_key? "sxmlId"
raise ArgumentError, "Duplicate key found on #{element.name} (#{element.attributes['sxmlId']})!" if @widget_hash.has_key? element.attributes["sxmlId"].to_sym

widget = eval "#{element.name}.new"
@widget_hash[element.attributes["sxmlId"].to_sym] = widget

element.attributes.each do |name, value|
eval "widget.set_#{name} #{value}" unless name.index("sxml") == 0
end

element.elements.each do |child|
handle child, widget
end

if element.attributes.has_key? "sxmlAction"
eval "parent.#{element.attributes['sxmlAction']} widget" unless parent.nil?
else
parent.add widget unless parent.nil?
end

widget
end
end

So, that's it! Pretty small for doing seemingly quite a bit, right? If you are wondering how to use the above "library", think of the SwingXml object as the root of your Swing component tree, while it is also a hash of the contained components. Typically, you would have a JFrame at the root, but you could even break them up more fine grained and have them be a panel or canvas of some sort. The components contained within the tree are accessible via their sxmlId values as indexes, which are an attribute you must specify on each xml element. You can even add more complicated things like layouts and whatnot with an sxmlAction which specifies how the object should be added to its parent.

As a simple example:

frame = SwingXml.new "<javax.swing.JFrame sxmlId=\"frame\" default_close_operation=\"javax.swing.JFrame::EXIT_ON_CLOSE\"><java.awt.FlowLayout sxmlId=\"frameLayout\" sxmlAction=\"set_layout\"/><javax.swing.JButton sxmlId=\"helloButton\" text=\"'Hello World!'\"/><javax.swing.JButton sxmlId=\"goodbyeButton\" text=\"'Goodby World!'\"/></javax.swing.JFrame>"

listener = java.awt.event.ActionListener.new
def listener.actionPerformed(e)
puts "Hello world!"
end
frame[:helloButton].add_action_listener listener

listener = java.awt.event.ActionListener.new
def listener.actionPerformed(e)
puts "Goodbye world!"
end
frame[:goodbyeButton].add_action_listener listener

frame[:frame].pack
frame[:frame].set_visible true

For easier reading, here is the XML but not embedded in the Ruby code:

<javax.swing.JFrame sxmlId=\"frame\" default_close_operation=\"javax.swing.JFrame::EXIT_ON_CLOSE\">
<java.awt.FlowLayout sxmlId=\"frameLayout\" sxmlAction=\"set_layout\"/>
<javax.swing.JButton sxmlId=\"helloButton\" text=\"'Hello World!'\"/>
<javax.swing.JButton sxmlId=\"goodbyeButton\" text=\"'Goodby World!'\"/>
</javax.swing.JFrame>

In the groovy port, I added some code to remove the need for javax.swing.JXXX and java.awt.XXX, but I didn't add this enhancement to the Ruby code, but it should be pretty trivial to add. That small addition makes the XML a lot less of a pain to deal with. Well... less of a pain anyways.

I hope you enjoyed this, and I hope to make these posts more frequent!

Mike