Thursday, December 29, 2005

Testing Abstract Code

I've been working on some java code lately and I came across something interesting. I have a set of domain objects that I wanted to make persistable via Hibernate. Now, these domain objects are meant to be used by other folks and they might want to map their Hibernate objects differently. So, I wanted to provide the support and maybe an example of how to map the objects. The problem was that I didn't want to bundle Hibernate just so that I could test the mappings.

What's a programmer to do? Well, to be Hibernate persistable, a class must have a default constructor and accessors for each field. Why not test for that? So, I quickly whipped up some code to iterate through the class path and find each of my domain objects. It then checks each class for the constructor and that each field has accessors. Wonderful. But, how do I know they work?

In the process of verifying everything, I had all of the reflection objects that I needed to verify that they worked as well. So, I invoke the default constructor and make sure no errors ensue. I then set/get each field with sample values and verify the results. If at anytime, an error happens, I output a reason and the test fails.

Now, I have a test that will keep me honest and tell me if I ever do something stupid to break my mappings. I can also enforce standards by testing if I wanted to. This is just another example of the power of meta-testing.

The design was simple. I had an object called ClassGenerator that was responsible for traversing the class path and providing class objects to an abstract method. It walked directories and jars respectively. The next object was a ClassFilter that would be given to the ClassGenerator to work much like FileFilter does. I did this so I could create a filter for my domain objects and outright reject classes that were out of my control. The last object was a Verification object that was responsible for making sure a class was correct (default constructor, all accessors worked, etc). The test is where everything was put together. He creates an inner class that subclasses ClassGenerator and hands it a DomainClassFilter. The inner class simply creates a new Verification object for each class passed into it and asks if the class is valid. If not, the tests fails and reasons are given why.

It was great to use this test to make sure I had done all of the mappings correctly and had not forgotten anything. The power of reflection compels me!

Friday, December 23, 2005





Saturday, December 17, 2005

I'm Batman!

Well, yeah! Especialy since I got a Batman buckle now too! =)


Batman, the Dark Knight


Neo, the "One"




The Amazing Spider-Man


Lara Croft


The Terminator


James Bond, Agent 007


William Wallace


Indiana Jones


El Zorro


Captain Jack Sparrow


Which Action Hero Would You Be? v. 2.0
created with


I had the pleasure of showing off Dabble at the latest Smalltalk User's Group. I didn't get a lot of time to play with it and yet, the demo came off easy and effortless. The crowd was in awe of how resilient to change it was. We started out with doing the To Do example from the ground up. But, curiousity soon got the best of us and we started to change the data and make purposeful mistakes. It was amazing how resilient it was. We changed types of information after already entering lots of it and watched how it didn't even skip a beat. Wow. There was an attention to detail that was inspiring. It's the same sense of awe that you get when you dig into the code of Seaside. Dabble drips class. The user interface was extremely easy to use and used a lot of javascript/CSS tricks that were used to enhance the user experience and not be showy. I was impressed. I think everyone there was as well. Good job, guys!

Sunday, December 11, 2005

Wise Words

No matter your craft. Words to live by from Randy Thom:



IDE Debate

Mark Derricutt sends a dose of reality to Smalltalkers via his excellent post on IDEs. In it, he writes:
Sure, alot of the time Smalltalk gives you this "everything is live" scenario, the problem I have is when Blaine (and others) say "there's no shutdown, compile, restart, and retry" which goes all the window when you start asking them about deploying an application.

I've been using Dolphin Smalltalk from Object Arts off and on for the last year for a small windows project, to get an executable you strip the running image down to the executable you ship to clients. As part of this "stripping" process, all the classes and methods that are unused in your application are (as they process implies) stripped/removed leaving you with a nice small redistributable application.

Deployment in Smalltalk is different from everything else. It's more of building down than building up. It just takes some getting used to. Dolphin makes it nice, you just add a category "Must Not Strip" to anything you don't want the automatic stripper to take away. What does the stripper take away? Any class or method not explicitly referenced. The things that get thrown away are methods that are only accessed via "perform" or other forms of reflection. Most Smalltalks allow you to add rules to stop methods from being stripped. It's a gotcha that stings most beginners. But, generally, less than 5% of your code is accessed only through reflection. It's not to say I haven't been bitten by it before. But, I've also been bitten by leaving out a jar in my lib directory at run-time in one of my java applications. It's something you don't forget and make once.

Later on, he talk about intellisense:
DOH! When your autocompletion gives you the wrong information it makes it more than worthless, I hope I don't get people saying 'oh but its because the IDE doesn't know what object you're wanting to complete...' cause that'll be playing right into the arms of pro-static-typing....

Ouch. You got us there. Since, Smalltalk is dynamically typed, it's hard to know what the type is so it just matches on symbols in the system. But, some intellisenses in Smalltalks are smarter. The ECompletion package in Squeak actually uses clues to find ou the type by taking advantage of the fact that a lot of people use the convention of "[a|an]Class" for their arguments. It only gives you the methods for that class if it can figure it out. But, intellisense in statically typed languages is better because they can know the type. It's more precise.

And then, he makes the final wake-up call:
Smalltalk IDEs may have provided all these wonderfull features for the last 20 years or so, but they also seem to have sat stagnant with the thought that they don't need to improve.

This hurts. I believe that Smalltalk IDEs have a lot of room for improvement. Several folks have made efforts to improvement(Whisker, Omnibrowser in Squeak, TrailBlazer in VisualAge for example). There's even efforts to improve the language (Traits). I wouldn't call Smalltalk stagnant and it hurts to see someone have that opinion. I still think with all of the improvements, we could go further. There's several things that I love about Eclipse (like hover over a method and its comment pops up).

I think for many years, Smalltalk was becoming stagnant, but recently, this has been changing. Squeak is undergoing a huge change. VisualWorks doesn't even look like the product from 5 years ago. And Dolphin makes huge leaps and bounds with each release. We need to keep our heads up and see what's going on and incorporate good ideas in Smalltalk and never be satisfied with the current state.

I would like to thank Mark for helping me stay honest....=) I know I tend to talk highly of Smalltalk, but it's because I love it so much. I never want to over-sale it. I'm just trying to be like the "soldiers in the village" and get people excited about what I think is one of the best languages around.

Saturday, December 10, 2005

I'm Shocked

Civility in blogging is contraversial? I'm a little shocked that someone was scared about giving a talk about this. I know there's things about there like the Bile Blog, but I don't like venomous talk and generally avoid things like it. I know he has a lot of readers and good luck to them. But, if you're going to spew hate into the world, I will not be reading it. You are the problem.

I want to debate topics constructively and not tear people down. I'm not afraid to put my name behind my comments and what I think. I want constructive, healthy debate. I like to think of the arguments of both sides and add my two cents. Mental vomiting and bad language adds nothing to the debate and discourages people to be speak up.

I would think in general people would accept civility and it shouldn't be something contraversial. I wonder if putting your name behind what you say is equally problematic. I hate anonymous posts especially of the putrid kind just because they seem so cowardly. I guess it's no different than the people who ruined newsgroups with their petulant rants and name calling. They have to go somewhere. You would hope that they would grow up and leave their veil of disguise. It's probably asking for too much.

Thursday, December 08, 2005 Update

The tuesday meeting (December 13, 2005) of the Omaha Smalltalk User's Group will include a LIVE demo of Dabble. How cool is that? Come see what everyone is talking about and why Dabble might be the killer application for Smalltalk. Or if you're just curious to see a cool Seaside application (who couldn't do without that?). See you all Tuesday!

Live vs. Dead

Torsten speaks about IDEs and he's right on the money. I generally look at Smalltalk's IDE as playing with a live patient. You are in the middle of a living and breathing system that reacts immediately to you. There's no shutdown, compile, restart, and retry. It's all happening right here and now. It's an incredibly cool experience especially when you realize that you can execute any code and inspect the state of the system. Eclipse on the other hand is like looking at your objects through a window. You can do some manipulation, but you can't mess around with the guts of the patient like you can in Smalltalk. The thing that truly shocks me is why Ruby and Python developers still try to mimic Eclipse (ie. run the code in a different process) in the IDEs available. There's no IDE for them that allows you to be in the middle of a live system. Why wouldn't you want that? I can't wait till Ruby does have a great IDE like Smalltalks. It turns the amp to 12 instead of a mere 11.

Wednesday, December 07, 2005

Humane Interface Debate








Testing To Stop Pain

Unit testing has taken the entire developer world by storm. The xUnit frameworks are simple and easy to use. I always have a test to verify any of my code. I love it. Recently, I've been using the unit testing framework for more than just unit testing. My view on testing has been to simply stop pain.

What does that mean?! It sounds like another meaningless mantra to beat developers with! Heaven forbid! But, I don't mean it that way. Pain to me is anything that detracts me away from my task. Bad design, crufty frameworks, and buggy code are painful. Unit testing is meant to fix the latter, but what about the first two? Could we do something about them? I think so.

The xUnit frameworks are so simple. They're really verification frameworks. If we change our thinking on what we verify, we can create a richer set of tests that go beyond mere broken code insurance. At work, if anything starts feeling problematic, I start thinking how can I fix it and write a test so that it never comes back. It's automating verification of problems. I take this beyond buggy code. I've so far used it to ensure deprecated frameworks are not used on new code and to support code coding habits (like ensuring file handles are closed). I plan on using it to ensure code is deployed correctly, raising flags on poor designs via metrics, and so much more. I'm basically thinking about using testing for prevention as much as verification. The xUnit frameworks are perfect because most of the hardwork has been done to integrate them into every IDE known to developers. A red bar means I need to go look at something. If a developer is sloppy enough to clean up their system resources, I want to know. Besides, a test can also have comments to give possible explanations why it failed. What a perfect training opportunity and no one has to lose any skin off their teeth for it. Think of it as a teacher and a kind enforcer of your teams coding rules. The point should be automating pain away so that once we fix it, it doesn't sneak up on us again.

Thinking beyond unit testing and code correctness is the next step. We have a lot of tools that determine the health of our project. Why not hook those into the unit testing framework as well? I'd rather know up-front if something is going to be a problem before it is. I want to stop the pain as early as possible.

It's time for the Smalltalk User's Group. This week we will be discussing Dabble and showing the video demo. It should be a lot of fun! As always bring your cool pieces of code!

Here's all of the details:

When: December 13, 2005, 7pm - 9pm
Where: Offices of Northern Natural Gas
1111 S 103rd Street
Omaha Nebraska 68154


Monday, December 05, 2005

Circuit Bending Blog


Friday, December 02, 2005



    When:December 5, 2005
    Where:Panera @ Eagle Run Shopping Center
    13410 West Maple Road
    Omaha, NE 68164

Tuesday, November 29, 2005

Agent Remote Control


Thursday, November 24, 2005

Dolphin 6 is a Reality!


Tuesday, November 15, 2005

Stephane Ducasse



Monday, November 14, 2005

Alternative Methods of Testing






Sunday, November 06, 2005

Why XML?


Declarative Programming







Wording and Definitions





Saturday, November 05, 2005


Here's all of the details:

When: November 8, 2005, 7pm - 9pm
Where: Offices of Northern Natural Gas
1111 S 103rd Street
Omaha Nebraska 68154




    When:November 7, 2005
    Where:Panera @ Eagle Run Shopping Center
    13410 West Maple Road
    Omaha, NE 68164

Sunday, October 30, 2005

New Me



Saturday, October 29, 2005

Early Binding Gotchas

I recently ran into code like this:

public class MyType {
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof MyType)) return false;
return equals((MyType)other);
public boolean equals(MyType other) {
return someValue == other.someValue;


public void testEquals() {
MyType myType=createExampleMyType();
MyType otherType=createAnotherExampleMyType();
MyType nullMyType=null;
Object nullObject=null;

assertTrue(myType.equals(myType)); //correct
assertFalse(myType.equals(null)); //correct
assertFalse(myType.equals(otherType)); //correct
assertFalse(myType.equals(nullObject)); //correct


So, what can you do?

public class MyType {
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof MyType)) return false;
return equals((MyType)other);
public boolean equals(MyType other) {
if (other == null) return false;
return someValue == other.someValue;


Great Idea


CD Extra Tracks


Friday, October 28, 2005

Cute And Fun


Wednesday, October 26, 2005

Being Sick Sucks


Sunday, October 16, 2005

Some Days Are Meant For Play



You can get the new version of LazyCollections on SqueakMap.

Saturday, October 15, 2005

Poor Interface


Monday, October 10, 2005

Re: Re: Dolphin's Command Framework

I got the following comment from Günther regarding this previous discussion:




Günther, guenni

setContextMenuFor: aModel 
| menu |
menu := aModel isNil
ifTrue: [nil]
[| contextMenu |
contextMenu := Menu description: 'IRiver'.
aModel actionItemDescriptions do:
[:each | | command description |
command := each key.
description := each value.
addCommand: command
description: description].
self tree view contextMenu: menu

| result |
result := super actionItemDescriptions.

| result |
result := super actionItemDescriptions.


Application vs. Data

Ravi Venkataraman wrote:











Sunday, October 09, 2005

Omaha Smalltalk User's Group Meeting


Here's all of the details:

When: October 11, 2005, 7pm - 9pm
Where: Offices of Northern Natural Gas
1111 S 103rd Street
Omaha Nebraska 68154


Saturday, October 08, 2005



Get Up


Sunday, October 02, 2005

Shared vs. Mobile Data






Firefly: Huh?


Thursday, September 29, 2005

Omaha Ruby User's Group

It's time to hold another great meeting of the Omaha Ruby User's Group. We'll be discussing Rails, Ruby, dynamic languages, and anything else we can think of. So bring your favorite pieces of Ruby code and your curiousity. Hope to see a lot of people there! Make sure you sign up on the mailing list. Here's the information of the when and where:

    When:October 3, 2005
    Where:Panera @ Eagle Run Shopping Center
    13410 West Maple Road
    Omaha, NE 68164

Wednesday, September 28, 2005

What He Said

I couldn't have said it better myself.
From Vincent Foley:
I compared dynamic languages and Java with riding a bike; in dynamic languages, you ride on two wheels and you get where you want pretty quickly. You can fall if the road is slippery, if you hit a rock or something, but with a little experience, these cases rarely occur. On the other hand, riding a Java bike is like having 8 wheels to make sure you don’t fall over, 10 people constantly around you, ready to catch you should you fall. You may be safer, but you’re not getting places faster than the dynamic biker.

Right on! Can I get an amen?

Monday, September 26, 2005

How not to make money

On the first visit to your site, I get this:
Mod_python error: "PythonHandler mod_python.servlet"

Traceback (most recent call last):

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 299, in HandlerDispatch
result = object(req)

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 1464, in handler

File "/home/hosting/users/metald/web/index.mps", line 23, in prep

File "/home/hosting/users/metald/lib/", line 42, in prep

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 593, in prep

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 389, in Session
timeout=timeout, lock=lock)

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 294, in __init__
timeout=timeout, lock=lock)

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 132, in __init__
Cookie.add_cookie(self._req, self.make_cookie())

File "/usr/local/lib/python2.4/site-packages/mod_python/", line 160, in make_cookie
c.path = dirpath[len(docroot):]

TypeError: unsubscriptable object

Ouch...Talk about bad first impressions. This is what happened when I tried to go to Metal Direct. I guess they don't like customers.

Sunday, September 25, 2005

Private: The Enemy of Extensibility

I was shocked to find out tonight that junit.runner.ClassPathTestCollector didn't account for tests in jars. OK, easy enough. I look through the class and find a methood called gatherFiles(File,String,result). It takes a file and determines if it is a test class. Well, a simple check to see if the file is a jar, add the class names of the entries which are tests to the result, and we were in business, right? Well, that's what I thought! So, I overrode gatherFiles, added super to let it do its job, and then, added my jar functionality. Simple right?! It didn't compile. It seems gatherFiles is a private method and I didn't have any visibility for the super. OK, I then just copied the original gatherFiles in place of the super and a little gentle refactoring. Everything compiled, but it worked like the old one. It then struck me. You can't override private methods. GRRRRRR! So, I wound up copying the remaining methods that I needed and removed ClassPathTestCollector as my superclass. It shocked me to know what should have been a simple refactoring, turned into a lot more, and it forced me to commit the worst of all sins: Duplicate code. Oh, did you want to see the jar code? Here you go:

protected void gatherFilesInJar(File jarFile, Hashtable result) {
try {
JarFile jar = new JarFile(jarFile);
try {
Enumeration enumeration = jar.entries();
while (enumeration.hasMoreElements()) {
JarEntry next = (JarEntry) enumeration.nextElement();
if (next.getName().endsWith(".class") && next.getName().indexOf('$') == -1) {
addToResultsIfTest(next.getName(), result);
} finally {
} catch (IOException ex) {

Nothing to it! Anyway, it was a fun bit of functionality to add, so that I can find and add all of my tests in my project now. I ran into these issues with private in Swing as well. I just think as designers we should not close our classes. The reason is because you never know what someone might need to do with your code eventually. Sealing means you know best. Just like I wanted to be able to handle jars in ClassPathTestCollector. If the original designer had thought of that, then he/she would have added that capability. Instead, they sealed off the class and forced me to sin. Don't make the same mistake.

Tuesday, September 20, 2005

Private Testing

David Buck and Charles Monteiro have been discussing how to make sure "private" methods in Smalltalk stay "private". Both have great techniques and it of course got me to thinking: "What a great use for unit tests!"

In all Smalltalks, we categorize methods of a class. Why not mark the private methods in some way? For example, use "private" somewhere in the category name (private, private-processing, private-accessing, etc). This way we know what should be private and what shouldn't be. It doesn't matter the convention just pick one. Now, that we know the private methods, create an object proxy that forwards all calls to the real object. This proxy would check if the method coming in is "private" and signal an exception if a method is "private" since only outside objects will call the proxy directly (Everything else will behind the proxy wall). Now, just pass the proxy around in the unit test as if it were the real object. Let the unit tests verify that we are not calling "private" methods and we have no run-time costs. Of course, we could get fancy and use method wrappers and #become:, but I will leave that as an exercise to the reader (or maybe a future blog entry?).

The main point of this post was to give yet another idea of how to make sure private methods stay private. I would love to hear more techniques. This technique that I just described is what I call meta-unit-tests. We are verifying meta-information about our program. I've used meta-unit-tests for making sure deprecated API calls are not sent in my code and that certain methods are implemented (ie don't have super that calls #shouldBeImplemented). We have a lot of information available to us at unit test time. We can take advantage of it!

Re: Dolphin's Command Framework

I got a comment from Anand that suggested that I change this code:
CommandMessageSend>>queryCommand: query 
| canSelector |
canSelector := ('can' , query command selector capitalized) asSymbol.
^(self receiver respondsTo: canSelector)
isEnabled: (self receiver perform: canSelector);
receiver: self receiver.
ifFalse: [super queryCommand: query]

CommandMessageSend>>queryCommand: query
| canSelector isEnabled |
[isEnabled := self receiver perform: canSelector]
on: MessageNotUnderstood
do: [:ex | ^super queryCommand: query].
isEnabled: isEnabled;
receiver: self receiver.

We got rid of the ifTrue:ifFalse: and the code is clearer. But, something bothered me about it. The MessageNotUnderstood could catch any MessageNotUnderstood further down in the stack (it might not be my canCommandSelector). What is a Smalltalker to do? How about this:
Object>>perform: aSelector onNotUnderstoodDo: aBlock
^[self perform: aSelector]
on: MessageNotUnderstood
do: [:ex | (ex receiver == self and: [ex selector == aSelector])
ifTrue: [aBlock value]
ifFalse: [ex pass]]

This message allows us to do the perform, but check to make sure it's the one we care about. Now, our CommandMessageSend code looks like this:
CommandMessageSend>>queryCommand: query
| canSelector isEnabled |
isEnabled := self receiver perform: canSelector onNotUnderstoodDo: [^super queryCommand: query].
isEnabled: isEnabled;
receiver: self receiver.

The code is about the same, but now we are only catching the MessageNotUnderstood exception that we care about and not any others. The code is still clean and we see another example of the power of Smalltalk exceptions. And I would like to thank Anand for the suggestion!

Monday, September 19, 2005

Oh Lucky Day

I pre-ordered Coheed and Cambria's "Good Apollo, I'm Burning Star IV" and it arrived a day early this morning. I immediately popped it into the player and was just floored. Great rock music from start to finish. I hear bits of The Cars, Led Zeppelin, Iron Maiden, and a whole bunch more. This is the way power pop is supposed to be. Oh yeah, they get the prog punk tag, but this is just wonderfully written music period. I haven't been this excited by a new band in a long time. I love the way they write incredibly catchy music that you never grow tired of hearing.

And then the mail man arrived with two more packages. I received Clutch's "Robot Hive/Exodus" and 3's "Wake Pig". Oh My God! I've never been blessed with this much good music in one day ever! Clutch is a mix of funk and stoner rock that pleases and 3 is like a blender of styles that just simply works. I guess progressive pop punk would be a tag, but you just have to listen to it.

All 3 albums are incredible slab of originality. Did I mention that they were great. Man, my ears are worn out! If anyone thinks that good rock music died in the 90's or you've been having a hard time looking for original great music. Look no further than these bands!

Great Advice

I have to apologize, but I have to pimp "Streamlined Object Modeling" yet again.
Personify Objects
Object model a domain by imagining its entities as active, knowing objects, capable of performing complex actions.
Talk Like an Object
To scope an object's responsibilities, imagine yourself as the object, and adopt the first-person voice when discussing it.
Do It Myself
Objects that are acted upon by others in the real world do the work themselves in the object world.

Live it, be it, model it! Let the design flow!

Smalltalk Unreadable? Huh?

Spotted this quote in JavaLobby via James Robertson:

OK, I've been there and done that with both Java (revisited old code from 3 years ago) and Smalltalk (revisited old code from 5 years) code bases. Now, both of the code bases were written by me and I didn't have a problem getting back into the code with either one. If you have well-defined names and intention revealing code, then it's NEVER a problem.

But, to get up to speed on existing code that I didn't write is another issue. I find Smalltalk to be easier than any language I've ever dealt with. It generally takes me no time to get up to speed with unknown Smalltalk code. Hell, I've been having a blast going through all of the Dolphin code recently. But, I've had my fair share of problems understanding Java code written by other programmers. And most of the reasons have nothing to do with language. It's mostly a matter of writing intention revealing code. Something that most good coders do unconsciously. I've seen my share of bad code in Perl, C, C++, Java, etc. But, I will say this, I find bad code in Smalltalk is much easier to read and understand. Since there's less rules, there's less to get messed up.

Anyway, it's amazing me that we are still having these discussions. Pick the language you love and write code. Stop whining about everyone else's. Each language has its strengths and weaknesses. I choose Smalltalk because it makes me more productive. If Java or Perl makes you more productive, then go write code in it! I do try to sell Smalltalk, but I don't believe in doing it at the expense of putting down another. I think Ruby, Smalltalk, Lisp, etc attacts a different kind of programmer than Java. And that's cool. There's nothing wrong with it. Now, let the Smalltalk flow!

Sunday, September 18, 2005

Dolphin's Command Framework

When I first started to play with Dolphin's MVP framework for building GUIs, I thought it was interesting. It forced you to keep all of the controller code in the presenter. The view was only responsible for view things, the presenter was the glue, and the model was where all of the magic occured. But, there was one thing that bothered me and that's how you used the command framework. From the examples, you override the #queryCommand: method in your Shell. Well, you ended up with code like this which I absolutely hate (BTW, this is taken from my first MVP application):
queryCommand: aCommandQuery

| command |
command:=aCommandQuery command.
(#(File Agents Help about) includes: command)
ifTrue: [^aCommandQuery beEnabled].
command == #saveAgentTape
ifTrue: [^aCommandQuery isEnabled: self tape name isEmpty not].
command == #recordPressed
ifTrue: [^aCommandQuery isEnabled: self tape canRecord].
command == #stopPressed
ifTrue: [^aCommandQuery isEnabled: self tape canStop].
command == #playPressed
ifTrue: [^aCommandQuery isEnabled: self tape canPlay].
command == #pausePressed
ifTrue: [^aCommandQuery isEnabled: self tape canPause].
command == #generateJavaScript
ifTrue: [^aCommandQuery isEnabled: self tape canConvertToScript].
^super queryCommand: aCommandQuery.

YUCK! If you go searching through the code, you find CommandPolicy, Command, CommandQuery, etc and I thought to myself, "Why did they create so many objects if the code turns out like the above?" The answer is the framework is smart and has a lot of parts to it. So, I browsed the implementers of #queryCommand: and I found an interesting class that implemented it: AbstractMessageSend! Well, the interesting thing is that normally you add commands as symbols to the CommandDescription for things like Buttons and MenuItems. But, you don't have to. You can put any object that understands #forwardTo:! And if you add #queryCommand: to your object to use as your command, then you can allow the command to decide when to enable/disable itself! So, I whipped up a little CommandMessageSend that disables/enables itself by calling a canCommandName method if it exists to know when to disable/enable the command in the menu.

MessageSend subclass: #CommandMessageSend
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
classInstanceVariableNames: ''

CommandMessageSend>>queryCommand: query
| canSelector |
^(self receiver respondsTo: canSelector)
isEnabled: (self receiver perform: canSelector);
receiver: self receiver.
ifFalse: [super queryCommand: query]


Now, instead of adding a symbol, I add this object. I now no longer override the #queryCommand: method in my Shell class! And the code from above no longer exists! No more case like if statements! It turns out that the Dolphin guys came up with really nice Command framework that works its way from the Command object itself and works it's way asking at each level of Presenters until it reaches the Shell. I can understand doing the simplest possible thing from the examples, but it doesn't show the power that they have given you. There's also a undo/redo framework for your code to take advantage of. Just browse references to the Command class. Fire up those browsers and start looking at that code! Dolphin has a lot of cool frameworks inside (look at DeferredValue for more fun).

Wednesday, September 14, 2005

I Got The Power

I've been spending an hour here and there on a mp3 file management system for myself in between on working on some of my other projects. It's basically so I can move files from my local file system, iRiver, and iShuffle. I've been writing it in Dolphin and having a great time. It's meant to be simple and I add features as I find things annoying. So, a production system it is not. Well, I decided to add drag/drop capability so I could do all my file operations within it. I've done drag/drop in several languages and environments in the past and I must admit Dolphin was the easiest. I looked at a few examples from the development environment and I had it all working within a couple of hours. WOW. I didn't even read any of the documentation. Most of my time was actually spent in the domain getting everything working just right. Most drag/drop frameworks I've used in the past are just a pain in the butt. I was simply amazed. Yet, another example of how nice Dolphin really is.

Ruby On Rails

Word on the street is that Sam Tesla gave a tasty sermon on Ruby On Rails at the Omaha Smalltalk User's Group last night. I couldn't make it because of work committments so I guess he's going to have to do it over at the next Ruby User's Group....=) He made a pdf available, so there's no reason not to enjoy its brilliance. Why do I always miss the good stuff?

Monday, September 12, 2005

Squeak Foundation

Towards an acting and communicating core for Squeak. I think this is a wonderful new development in the Squeak community. It's been a long time coming. I love the following quote too:
We will follow the chicken and pig Scrum metaphor: Doers or Core will have the power to do something and talkers will be less considered, even if we will listen to them.

It seems process is getting in place to fund and direct energy in the Squeak community. I think this is exciting! I would like to thank everyone involved in this. Let the Squeak flow!

Saturday, September 10, 2005

Omaha Smalltalk User's Meeting

This month we will be doing a two fisted meeting! First up, we will show the brilliant Avi Bryant Seaside demo from the Vancouver Lisp Meeting. Then, Sam Tesla has been kind enough to show us Ruby and Ruby On Rails. So, it's going to be a meeting not to be missed!

Here's all of the details:

When: September 13, 2005, 7pm - 9pm
Where: Offices of Northern Natural Gas
1111 S 103rd Street
Omaha Nebraska 68154


SortedCollection, Block, and Polymorphism

| collection |
collection := Array
with: 'second' -> 'turbine'
with: 'third' -> 'earth'
with: 'fourth' -> 'good apollo'.

And it returns:

a SortedCollection(
'fourth' -> 'good apollo'
'second' -> 'turbine'
'third' -> 'earth')

collection asSortedCollection: (Message selector: #key)

Or even write a method to do the comparison:
compare: anObjectA to: anObjectB
anObjectA key <= anObjectB key




Domain Specific Languages

I still see old world flat file specifications like the following:

9(8)Some DateDDMMYYYY
9(6)Some TimeHHMMSS
x(20)Lovely NameA Good Name


(9(8) someDate asDDMMYYYY)
(9(6) someTime asHHMMSS)
(x(20) lovelyName)
(x36) filler)


parse: aStream
typeInfo := eachLayout first.
typeLength := eachLayout second first.
fieldName := eachLayout third.
rawData := aStream next: typeLength.
data := rawData perform: converterSelector.


XML Generation In Smalltalk

xml := BtbXmlRenderer on: writeStream.
(second (third '"fun"'))
(fifth #sixth: 56)).

And this generates the following XML:
<?xml version="1.0"?>
<fifth sixth="56"/>


Monday, September 05, 2005



Good OO Thoughts

From Steve Dekorte's blog:

1. the number of arguments passed in message calls
2. The number of instance variables in the objects




Sunday, September 04, 2005

Rule #67 in Design

NEVER clean up resources you did not create

I hate to pick on Java, but I found a great example of this in the Java API of all places in the javax.swing.text.html.parser.Parser class. I removed a lot of the code from the method to concentrate on the violation:

* Parse an HTML stream, given a DTD.
public synchronized void parse(Reader in) throws IOException {
try {
} finally {

Basically, you pass in a Reader object that obviously you have to CREATE. And what do they for you? They free your resource that you passed in. Heaven forbid, you would like to do something else with it. Besides, why would you do that? Well, that's not the point. In design, I NEVER clean up a resource I did not allocate. If it is passed into me, I do what I need to do with it and that's all. On the other hand, if I allocate it, I take pains to make sure I deallocate it. This is what I did in my C/C++ days and it was a great rule of thumb that prevented a lot of problems.

Friday, September 02, 2005

Is That All?

Taken from the comp.lang.smalltalk.dolphin:

> Besides the IdeaSpace, what else is new?

Well, off the top of my head, and in no particular order:
1) New look tools with sliding panes (imaginatively called Slidey Inny
Outey Things, SIOTs) :-)
2) New look Resource Browser with iconic categories and preview pane. nloads/6.0/images/d6rb.png
3) New look View Composer with sliding resource toolbox and Inspector
panes.  The View Composer now supports undo. nloads/6.0/images/d6vc.png
4) Improved garbage collector giving approximately 20% speed
improvement overall.
5) Compiler now supports true block closures and not just a
Smalltalk-80 block semantics.
6) All code editing is now done using the Scintilla code editor.  This
means we get away from the vagaries of the Windows Rich Text Control
and also we now have auto completion (IntelliSense). nloads/6.0/images/d6ac.png
7) New "literal filer" for storing views which opens up the resources
such that their contents can be refactored etc.  Storing resources in
this way also greatly simplifies the image stripping process at
8) New Sockets2 package that uses overlapped/blocking calls rather than
asynchronous messages.  The old package is provided for backwards
9) The Refactoring Browser rewrite tool has been included as a plug-in
in the class and system browsers. nloads/6.0/images/d6rwt.png
10) The class and system browsers now have a Code Mentor plug-in that
comments on the style of your code.  It runs the analysis in the
background as you work and is based on the SmallLint facility that
comes with the refactoring engine. nloads/6.0/images/d6cm.png
11) Views now support background colour inheritance.
12) New TabViewXP view that supports XP-style tab views in all
orientations (unlike the standard Windows control).
13) Dynamic syntax highlighting in all workspaces as you type.
14) Workspaces highlight compilation errors and warnings with squiggly
underlinesand will display help for these when the mouse hovers over
15) Various new view controls such as: SysLink, LinkButton,
MonthCalendarView, SpinButton.
16) Windows XP application manifest is now included as part of the
version resource in deployed executables.
17) Application deployment now creates a complete XML based contents
list of the entire application.  This can be browsed from within
Dolphin using a class browser to see exactly what methods and classes
are present in the application. nloads/6.0/images/d6cm.png
18) New Method Explorer which replaces the old Method Browser to
provide a hierarchical trail of browse requests.  The aim, like with
the IdeaSpace, is to reduce the number of open windows while working
with Dolphin. nloads/6.0/images/d6mex.png
There are dozens of other minor enhancements and bug fixes and probably
some other fairly major ones that I've forgotten but the above should
give you a flavour of what is coming in Dolphin 6.
Best regards,
Andy Bower
Dolphin Support

WOW! That sure is a lot of stuff to pack in for a release. I'm beyond excited. I'm so lusting for Dolphin 6.0. I feel like a kitten that can see the cream, but can't lap it up. Dolphin on!

Thursday, September 01, 2005

What kind of technology do you want to create?

From Donald Norman's "Things That Make Us Smart":
When I speak of the power and virtues of technology, I am referring to soft technology: technology that is flexible, that is under our control. Hard technology remains unheedful of the real needs and desires of the users. It is a technology that, rather than conforming to our needs, forces us to conform to its needs. Hard technology make us subservient; soft technology puts us in charge. Automating tends to be a hard use of technology. Informating tends to be soft.

So, when you are creating your next program or framework, think to yourself, "How would I want to be treated?" I bet you would prefer soft technology over hard. Let's make the user experience better all around. I promise to take the above quote to heart in my future endeavors. Take the oath and let's start delighting our users together.

Tuesday, August 30, 2005

Coheed & Cambria


Sunday, August 28, 2005

Too Funny


Saturday, August 27, 2005

Excited about Squeak 3.9


VOIVOD Guitarist DENIS 'PIGGY' D'AMOUR Dead Of Colon Cancer


Friday, August 26, 2005

The Future and The Ordinary





Thursday, August 25, 2005

Service Provider Went Nuts


Wednesday, August 24, 2005

Amen, brother


I, Prototype



How hardcore do you want to be?
How many lifetimes to you want to waste?
