11/26/2007

New Machine - Tools

Life is all about acquiring the coolest tools so for all the Windows tasks that i used to do with ease I need to find the most efficient way to do the same thing on the Mac.

This is a little bit of a tight rope walk because learning something new is about doing things a different way but it's also about being efficient so you have to try both and see which is the best.

So these are the tools that I have currently installed that seem to help a little. I expect that we will need many more,


JumpCut multi-clip support
Quick silver fast access to anything on your computer

New Machine - Default preferences to change

There seem to be lots of settings that appear to be different from what I expect. Since what I expect is a windows experience I wonder if I should be changing these. At least if I document them I can reverse the decision later.


System Preferences
Security

General
- Defaults to no password and auto-login.
- Check the "Require password to wake this computer"
- Check the "Disable automatic login"

Firewall
- Defaults to "Allow all incoming connections". Very bad.
- Switch to "Allow only essential services".

Keyboard & Mouse

Keyboard
Use all F1, F2, etc as function keys
- Defaults to disabled because you always need to
adjust your screen brightness? Silly people.

Trackpad

Use two fingers to scroll
- Enable this so you don't have to move the mouse to
the scroll arrows

Allow horizontal scrolling
- Enable the horizontal while you are about it.
Not as useful but nice when it's needed.

Clicking
- Enable this so that you don't have to move your
fingers so far to click something,

Dragging
- Dragging windows with the mouse is easy and
only requires one finger.
- Drag lock appears to be enabled whether the checkbox is
checked or not.

Tab trachpad using two fingers for secondary click
- Defaults off but is a better way to get the context menu than
holding down ctrl and clicking.

Keyboard Shortcuts
Full Keyboard Access
- Defaults to "Text boxes and lists only" instead of "All controls".
Mac's hate the keyboard.

Accounts
- Unlock the properties and select "Name and password"
so hackers can't see a list of usernames.

New Machine - First impressions

My first impression was that it was really heavy. I wanted a big machine so I can't complain but man is it heavy.

Plugged in the fancy magnetic power cord and it started up perfectly. A short setup and I am on the network and ready to go.

Second impression, when the setup started it played this welcome video full screen on the hi-def glossy monitor. I can honestly say that I almost fell over. Stunning.

So I am logged in and the "dock" shows some applications at the bottom of the screen and the finder appears. The finder window is small so I try to resize it but, third impression, the cursor doesn't change when you hover over the window frame. Strange that it doesn't offer that feedback.

While wondering how to find Safari I notice a little bouncy thing in the dock. I look close to see that it says, "Software Updates". Wow they are already trying to improve my machine for me. Nice Apple.

The update starts OK but with another UI problem. I thought Mac were supposed to be user friendly. The first option is "later" or "Install and Restart". Well after the surprise of having to restart has passed I select it "Install and Restart".

It asked for a couple of legal agreements from iTunes and Mac OS X and then to my astonishment it asked me again if I want to restart. Didn't I just answer that question?

Ok, here is another one. Being a developer I like the keyboard over the mouse but when I press the "Enter" key on a mac it seems to want me to rename the icon? That is just not logical. To start Safari I have to use the mouse and double click it.

Yes, yes, you are going to hear some winy old Windows guy complaining about having to do things a different way for a little while.

Here is another example. Safari opens and I am blasted by more ads (The PC Mac adverts are obviously propaganda). I am sucked in and click on a link to a new Alecia Keys song. I now have to setup iTunes which seems reasonable. One of the dialogs explains that "iTunes can download album art", which sounds nice but I read on, to do so I need "to create an account on iTunes", "Just go to iTunes and click on 'Get Album Artwork'." Does it sound odd to you that a dialog is explaining to me that I need to go to a web page and which link to press without including a hyperlink to the place? I have no idea where iTunes is or where this link is. This is just bad UI.

So quite apart from the fact that the marketing people have worked out a way to get me to create an iTunes account for something that is freely available on the net, I am blown away by the horrendous user interface again.

-----------------------

Ok, I am a dummy. While user interfaces should be built for people like me I now feel stupid. The dialog explaining all this stuff that I need to do isn't actually expecting me to do it. I give up my search and press the Next button and guess what the options are? "Yes - take me to the iTunes store" or "No - don't". I think I should have known that these options were going to be available while I was studying the previous dialog. My bad.

Alecia Keys is still not playing but I have the iTunes store in front of me. If I remember the instructions from that dialog then I am supposed to select "Advanced" and "Get Album Art". Lucky I used a pencil and paper to note that down. Perhaps that should be Mac new ad.

PC - Hi Mac.
Mac - Hi PC.
PC - I hear that I need to use pencil and paper to use your crappy interface.
Mac - Wait, just press the Next button and everything will be explained.

but this little saga doesn't end here. You should see this, it is really funny.

So I press "Advanced" and select "Get Album Art" as instructed. Guess where it takes me? Yes, that's it, the iTunes store that I am already looking at. Wow, this stuff is crappy. It turns out that that dialog was completely unnecessary, all I needed was a button titled "Create iTunes Store account so that you get Album Art" and I would have been happy.

You will laugh at this. Turns out I already had an iTunes account. Go figure.

So finally I got to listen to Alicia Keys. The song sucked.

New Machine - Arrived CINCINNATI, OH

While munching on Yogurt and a nice bowl of raisin bran, the nice FedEx man arrives and can you believe what he is carrying? Yes, a little brown box with a smaller white box in side.

11/25/2007

New Machine, Now in MEMPHIS, TN

At 4:27pm on November 25th a short flight to Memphis puts it 2 states away.

New Machine, Now in ANCHORAGE, AK

At 1:36pm on November 24th the MacBookPro has arrived in the US. They are so kind to be traveling on a Thanksgiving weekend, if only they would go a little faster :-)

New Machine, From SHANGHAI, CN

What do 2.6, 4, 200, 7200, 17 and glossy have in common? They are all stored safely in a little, flat, white box with an ON button.

If you haven't guessed yet, it's my new MacBook Pro. After a lifetime of Unix and Windows it's time to start on another adventure.

I have to admit that it feels a little like I am just switching monopolies. While the Apple is not as large it seems just as controlling. Based on the delayed Java releases on OS X and the no Java on the iPhone this is not going to be all roses.

However, my reasoning stands. I basically have three reasons to change.


  1. My Windows XP environment on my trusty Sony Vaio is old and in need of an upgrade.

  2. The hardware compatibility issues with Windows continue with regular blue screens especially with graphic intensive applications.

  3. The upgrade path for Windows seems fraught with problems. Vista's security issues persist with most continuing to run the 32 bit on 64 bit hardware.


I can't say that the migration to a Mac will be ideal. I know they have hardware issues and as they become more popular they will inevitably encounter more security issues.

The tipping point is for me came when I realized that moving to OS X doesn't preclude me from running Windows in a VM. I watch a buddy of mine use Parallels run Vista on OS X and everything just works.

11/21/2007

Complexity, a perspective

Complexity, ranked high due to ignorance, is not complexity, but ignorance.

9/23/2007

JRuby Rails Project Day One, Lessons Learned

I blogged a while ago that Ruby was the way to go for the best language experience for the future. To that end I am starting to build a new site using Ruby on Rails and focusing on JRuby so that I can deploy it to my existing Tomcat hosting service.

The site is going to present a new company Sewing Seeds of Literacy which is a venture my wife is embarking on to help supply books to under privileged children. I was hired as the technical help.

Background over.

I started by using the NetBeans V6 IDE and its Ruby Rails integration. This is a major step forward in IDE Ruby support and integrates with JRuby easily.

So, right click, New Project, Ruby Rails Application, and you have your first Rails runtime on top of JRuby. This is really nice.

Initial setup over.

The first problem is the database access. The JRuby environment requires JDBC access. The database.yml setup is the same but there is an ActiveRecordJDBC gem that needs to be installed to manage the connection from ActiveRecord ORM library to the JDBC drivers.

This is all detailed on the Headius site.

Then these JDBC drivers need to be available on the classpath. I am going in with MySQL so I needed to add the mysql-connector-java-5.0.4-bin.jar to the classpath.

Unfortunately there are some competing configuration issues going on here.

1) I had downloaded and installed my own JRuby environment and NetBeans comes with its own. This causes problems because each environment installs its own gems. You can set the environment that NetBeans will use in

Tools->Options->Miscelanious->Ruby


2) I had my own c-ruby environment and my path specified jruby/bin before ruby/bin but the JRuby "rake" command is unix only so I was inadvertently running the c-ruby rake command expecting it to manage my migration properly but it couldn't find the JDBC gem.

Anyway, after much googling, Foo had the answer. You need to create a "jrake.bat" in your JRuby bin directory that looks like this:
@echo off
jruby -S rake %*


Now you can jrake in your jruby environment and rake in your c-ruby environment. There are references to "jake" here and there but nothing concrete.

3) Now that we are running the right commands we need to add the appropriate jar. There are a couple of ways to do this

o Create the CLASSPATH environment variable and point it to your jar.
o Copy your jar into the JRUBY_HOME/lib dir.

One thing that does NOT appear to work is adding the jar to the Netbeans project classpath.

I chose to copy to JRUBY_HOME/lib for the time being but I don't like this as a long term solution since it means each environment I deploy to needs some extra installation work. Ideally, the jars would be deployed with my war file so they are made available to the containers classpath automatically.

JDBC Jar configuration over.

Right click, generate, controller, simple. Right click, generate, model, no sweat. Right click, generate, migration, done.

These are basic Rails concepts that work just as well in a JRuby environment. They make application development very easy.

mysqladmin create MYDB_development
jrake db:migrate


Database creation over.

Now I have a model and a model test but I can't run them because there is no database. Yes, we just finished using our cool new migrations to create a database but that was the development database which is the default RAILS_ENV. We need the test database created from the same migrations. This is not so easy. In fact it is really hard. None of the books talk about it, all the migrations help pages just talk about the default development case. We are going to have to run our migration in test regularly and eventually in production as well so there has to be a solution.

Along comes a new plugin called Migrate Test DB Rake Plugin . This is a rails plugin that performs a database schema create on the test database before rails tests are run. This means that when you execute "jrake test" it will create the schema first. This is not effective when running Test::Unit in NetBeans.

So, I don't see that this is a good solution. As a side effect of testing I am able to create a test database schema. Still doesn't solve the production database situation but that is a little way off.

Model create over.

Oh, now I find the best documentation, on the JRuby Wiki. This entry talks about the "goldspike" plugin which adds lots of java'esk features to rake like creating a war and how to declare the mysql jar as a dependency.

9/21/2007

Maven: Why does it have to be so hard?

Every project I start I try to use Maven. It seems like the right choice but I consistently fail. Every step is hard. It's not just that there are infrastructure hurdles, but the commands are hard, the POM is complex and nothing is easy.

This J bites.

Ok, enough whining. Maven is the right way to manage your build environment simply because it is the only tool that manages your dependencies. This is a simple concept.

We can argue that ant has sufficed for a long time and that is true. So, we can argue that the dependency complexities that we face are actually not that hard since we appear to be able to work it out without another tool, but wouldn't it be great if we could leverage the learning that others have already put into setting up the correct dependencies?

Well I am installing grails, an ant solution, and integrating CXF and Mule. I am facing continuous versioning problems with all the xml/soap/ws etc jars. I am sure that when I have solved this problem, I will promptly forget it and have to solve it all over again for the next project.

I would like to be able to capture the solution in a POM so that I could reuse it even if no one else does.

So, what is step one. Create a maven project. This is so hard. I can't believe they make us do this. No wonder this tool is taking so long to gain acceptance.

mvn archetype:create -DgroupId=com.company.project-DartifactId=project-name-DarchetypeArtifactId=maven-archetype-webapp


Yes, that is the command to create a project, and I didn't even specify all the other version options that they mention. All it does is create this:

./pom.xml
./src
./src/main
./src/main/resources
./src/main/webapp
./src/main/webapp/index.jsp
./src/main/webapp/WEB-INF
./src/main/webapp/WEB-INF/web.xml


It doesn't do much but it does allow us to enforce standards and, when we develope our own archetypes will improve project structure consistency accross the board. This is all good but why do I need to pass in system properties? Who ever heard of a command line interface that makes you declare system properties.

Perhaps it could prompt for the required fields like "grails create-app". Perhaps there should be a web page on the maven site that will help. I had to go through google to find it. Their quick start doesn't even talk about it.

I know, I know, I am whining. I could probably contribute to the project myself, it's open source and all that.

There is an Eclipse and NetBeans plugin that makes life a little easier.

There comees a point when we learn to love the new tool. I just pasted a glob of xml into my POM file because some CXF/Maven web page told me to, saved it, and the maven eclipse plugin promptly downloaded all the jars required to bring a CXF web service up and running. This took me an hour or so the first time. Maven just made my life easier.

...

And again I am dashed to the jagged rocks of the learning curve. It appears maven doesn't use the JAVA_HOME environment variable to determine the JDK version to use and it is defaulting to JDK 1.3 which is not even installed on my machine. I have annotations so it will not work anyway.

I suppose it makes sense because it is requiring explicit version declarations for all other jars so why not the rt.jar but it is not telling me how to specify it.

This brings up the odd balance in our lives of detail vs default. If I require everything specified I know my build will always be correct. If I allow default selections using JAVA_HOME for example, it may fail but will usually work.

This is why maven is so hard to deal with. Nothing is easy. Specify or die a bloody death and don't expect to block the gushin wound with documentation because even google is lost.

...

Ok, I found it, System Dependencies

...
Oh wait, that is wrong, doesn't work and I don't know what it does though it sounded so close. Infact, we want this Compiling-J2SE-5

Man that took another 30 minutes, I almost gave up on Maven again.

...
I might be back to loving maven again. Once you have run your "mvn package" to create your war file you can run "mvn tomcat:run" which will run tomcat in place from your generated war file. Now that is cool.

...
Well, while I can't expect maven to solve all my problems, since it's intent is to solve dependency problems I did have that expectation. Silly me.

The CXF xml glob that I pasted to get all the CXF jars and dependencies downloaded apparently missed the SAAJ jars. I expect I will have to find and add these to my project file manually.

I am starting to feel as though I might be starting to understand Maven, even if it isn't doing what I want.

8/22/2007

Simplicity

Stop doting your eye's and just capitalize.

7/28/2007

Waterfall Symptoms

As I stand in a sit down status meeting to listen to another hour long discussion I ponder what is going on to see if I can offer some help. The obvious suggestions have already been ignored: stand up during the meetings; stop designing the system in meetings; stop with all the detail please, just a summary is all I need.

This meeting is a little special though. We have a list of components to be completed before we go live and another list of the outstanding bugs. 20 of one component and 197 of the other. We go live in 6 weeks.

An analyst, that doubles as QA tester, spent their weekend testing but entered bugs like "couldn't test" because of environment problems. The release process is still pretty new and untested.

Our leader asks for QA of a new module and the same dedicated analyst asks for help. There is none, of coarse, just a few extra of their hours in their day. They were allocated to their kids, but they are dedicated folk. Dedicated to their work I mean, can't be dedicated to work and kids on a waterfall project. Laughable.

They mention code freeze, except for bugs of coarse; you understand, can't code freeze code that doesn't work. Laughable.

6 weeks left and now we start raining in scope. Oh wonderful, just in time. Laughable.

QA has no automation so there will be no regression, just wild retesting. They do a great job, work really hard and find lots of bugs. I just wonder how many are missed for the next go around.

The project plan is stored in MS Access, a horrible solution, that few people use. We just code anyway, why should we know what the plan is, we weren't part of its creation, or its revisions. It was presented to us once, I asked some questions about it which had the usual optimistic answers.

Question: "There isn't enough time to complete coding and QA testing before the release date"

Optimism: "Oh, that's ok, they will run in parallel. Each component we finish will go into QA test."

It all sounds so logical. Of coarse, I am an Agile developer, parallel coding and testing are the norm but my Agile projects are setup to support that feat. Waterfall projects aren't, well this project isn't anyway, seems a shame to speak for all falling water.

Of coarse the reality has proved itself over the optimistic plan. It has a way of doing that. The QA regression testing is required and is being attempted. Best of luck to them. They work so hard. They deserve success.

I try to get the ant scripts to release to production. Not to big a job, shame I couldn't get them to work on it 6 months ago. Anyway, I am talking to the tech lead and we have to have this finished by tomorrow. There is a problem with my ant properties so he exclaims that he will manually complete the production deployment so we don't need ant.

"We don't release to production often anyway, so it doesn't matter"

I suggest that the less you deploy the more important the scripts, after all we got dev deployments reliable months ago, and we really want production deployments to work first time every time right?

"Yes, that's right, but we need it by tomorrow. We can try again in two weeks."

He really does have the best intentions. He has been put in a predicament. No production release practice for 10 months, now we have about a week to get it right.

Why does our industry do this to itself? They can't predict where the next problem will be before it arrives. Experience? No, they have lots. Understanding? No they are smart people. They have always done it this way. This is how software projects always work. This is just the life of a software developer. It is all we can expect. Why change.

If it weren't for change,
I couldn't tell that I am standing still.
If it weren't for standing still,
I couldn't tell that the world around me was leaving me behind.

I see what I see with clarity,
I understand what I understand with certainty,
With this clarity of certainty,
I stand and watch and re-affirm my motionless state.

If I stand on the certainty,
That my knowledge is true,
Then my only conclusion must be,
That all that I see is foolish change.

The gulf between knowledge and change, stands in a persons need,
A persons need depends on their situations urgency,
A situations urgency is created by those who don't change,
so the lack of change is our choice, because that has always been our situation.

New Knowledge vs Productivity

Update: 08/22/2007: add references to J curve

I can get task X done using knowledge I already have. I would take longer if I used a technique that I don't currently know.

However, if I learned a new technique I might complete task Y so fast that the slowdown on task X is insignificant.

This is the balance of the J curve. The J idea proposes that your productivity remains flat until you learn something new. At the beginning of your learning your productivity decreases until your skills are sufficient to surpass your original productivity.

The amount we produce is related to our current position on the J's learning curve and the number of J's in our past.

So, worst case, you could imagine living on the downward slant of the J forever. There is always something new to learn after all, why produce when you can learn. I guess pure research organizations work like this.

The other worst case, is never entering the J. Living your life with a static set of knowledge.

OK, so how often should we dive into the J?

Life needs to exist,
In a rising J,
With every day,
Finding another rise.

If the bad poetry doesn't make sense then consider learning 5 things at once and every day push one of your tracks past the base of the curve.

Growth ends with the belief that you will be less productive by learning.

Do something new today, even if it hurts. Oh, and it will hurt.

References:

Meilir Page-Jones: The Productivity Curve

Gerry Weinberg: quoted as part of his pinball analog

Amazing Image Integration

This movie has been around since May but I just found it and just in
case others havn't seen it, here it is.

http://www.ted.com/index.php/talks/view/id/129

The future of connected imagery is here.

7/06/2007

Twitter

Yes, I am now sending tweets. Not sure why but it appears to be addicting.

Twitter is another social network but is far more focused in its goals. It just asks "What are you doing" and with frequent updates you end up with a general idea of what your friends are doing.

Perhaps this is just too much information and no one really cares but I think that is what it is all about. Why does and now much will they be able to pay?

With a simple beginning there are now addons to the twitter service like a search of all the things that people are doing and, my personal favorite mashup, TwitterVision which merges the posts with the geo locations of the poster and swoops you around the world from language to language and irrelevant activity to irrelevant activity.

But don't count this thing out yet. Check out my personal twitter vision. There are many times that we need to keep track of things. Oh, did we think this was limited to people? When are you going to get that new watch that will tweet so you never loose it. Should FedEx make their packages tweet? It's just a 140 character piece of text but twitter vision encodes ":L[position]" into it as a really simple way to track things.

FexEx, of course, built their own package tracking system back in the days when web services were new and SOA was a Canadian SO. If the task was started again today would they have chosen to leverage existing web services.

Each web service we build we examine granularity as an architectural problem. Perhaps the success of twitter indicates we should stop examining and just think smaller.

Who knows perhaps your next watch will make a request for the time somewhere.

Visual Studio 2005 and ReSharper

I have used ReSharper with VS 03 in the past but decided to try the new VS 05 features before installing the new ReSharper version. After fighting with the stupid stupid VS features my course is clear.

ReSharper is to C# what Eclipse is to Java. A rebirth.

6/26/2007

Java, C#, Groovy, Ruby, Python

Is the question "which" or "which ones"?

I am a member of a local user group that exclusively pitches Ruby as the savior of all things linguistic. I had made a strategic decision to learn Groovy instead because it integrates better into my primary language, Java.

This has worked pretty well for me up to now with a couple of jobs getting groovyized nicely.

Well, Chris Nelson, mentioned something to me a few user groups ago that just sunk in today. An extension to the logic of why I chose Groovy.

If we assume the future is a combination of the best of today. Perhaps a tenuous bet but I am an optimist. Then we have to assume that a VM is the correct runtime environment for future systems. This knocks out c-Ruby from the running.

If we think that dynamically typed languages win over statically typed languages then we have to choose Python, Ruby or Groovy as the most blogged about at the moment. I am completely sold on dynamic languages and have been for years.

I asked Chris why he choose JRuby/Rails over Groovy/Grails since he is a Java developer from long back (Trails). He answered, "It's a different language".

My first impression was that Ruby was a different language as well so what's your point. Then today, while reading Charles Nutter's response to Ola's IronRuby post it occurred to me that the language Ruby is key for the simple reason that it is likely to be the first multi-vm language and already represents the best of what a dynamic language can offer.

Based on this there is one choice, quit groovy, learn Ruby in what ever form and the runtime environment will follow.

Did anyone notice how I dropped python so fast? Dynamically typed and runs on JVM (Jython) and CLR (IronPython) today but I hate tabs :-)

Unfortunately, the question is "which ones". Things move to fast to play just one pipe.

6/20/2007

Standup Meetings, for Accountability not Communication

We Agile folks like out stand-up meetings but when asked why we do it we usually start talking about communication being a core principle.

A recent project involved a customer that was tentatively interested in Agile so started doing stand-ups. When it came to a month or so before my departure I stopped leading to help encourage the team to take ownership of the new processes that they had been learning.

The first thing that went was the stand-up meetings and the result of this lead me to the decision that we don't stand-up for communication. The best reason for stand-up meetings is to force every programmer to prove that they are working to the plan instead of just working.

This forces plan driven work which is prioritized and focused. My customer quickly descended back into panic driven work with programmers being approached by QA reps telling them of the latest problem and urging them into action. The plan was forgotten.

The chatter and sharing is nice and there are certainly other benefits to stand-ups but from a management perspective we do this to ensure that we are driving accountability for everything that we do each day.

The shorter iterations of Agile drive accountability to the customer. The daily discussion on what we are focusing on drives programmers accountability to themselves and their team.

6/19/2007

Star Wars ! What really happened after the Deathstar blew up

This is really funny.

[snipped old dead version]

The moral of this story that before long everything will be a copy. Thanks for the comment Mr Anonymous.

The yahoo version is still active.

6/15/2007

TIP: Dos Sleep

I needed a batch file to sleep between starting up a couple of processes but dos doesn't support sleep. Google found me this result which gave me the idea but their solution is wrong.

The actual answer is this:

ping 1.1.1.1 -n 1 -w 10000 > nul
In this case we are pinging a non-existent IP address, once, and timing out in 10000 milliseconds.

Of coarse you could pop this into a sleep.bat to centralize it
cd c:\windows\system32
copy con sleep.bat
@echo off
ping 1.1.1.1 -n 1 -w %1% > nul
ctrl-Z
Now you can just type "sleep 5000" to sleep for 5 seconds.

The actual resolution of this timer is one second or more. Any number less than one second is going to end up with a 1 second'ish delay.

The cost of this is one network ping with a standard 32 byte payload. The total message is 74 bytes on a Windows XP machine. This is low cost for a couple of sleeps in your program. If you want to do this all the time then you may want a less hackey solution.

The better solution might be to use the Windows Resource Kit which includes a sleep.exe command.

6/14/2007

Speed of Time

If you could set the speed of time,
how long would it take you to change it.

5/11/2007

MonoRails - .Net is cool after all

After two days of fighting with msbuild I thought that I was going to loose hope but along comes MonoRails. We all know that Rails rocks, we have loved tinkering with Grails and now we find that wherever we go someone is building another version of this idea.

For the uninitiated, go and learn Rails first, it's the granddaddy of them all. These are new ways to build web applications, they obey the idea that conventions can be more productive and just as flexible as configuration files so you type in the name of something and it magically gets extra powers just because you spelled it correctly. Don't be afraid of the magic, it is your friend.

So, MonoRails is more of the same but here are a couple of differences that I noticed on my first night at playing with it:

  1. It is normal statically typed C#. All these frameworks use dynamically typed languages to achieve much of the magic. Injecting methods, imbuing properties, you name it they do it. The static language approach is certainly going to offer some additional challenges and, some might say, reduce the benefit of this implementation of the new approach.
  2. Parameters posted from a form are dynamically mapped to a controller method and passed in as parameters. Perhaps not ideal for large forms but certainly the simpler ones can use this instead of having to deal with a property hash. They can also mangle the form names into an object like good old structs forms.
Ends up at the same place. After a couple of hours going through tutorials I have another tabled scaffolded.

5/10/2007

Tripping in .Net

It has been a few years now but I have another opportunity to play on a .Net project. Being so used to the Java way this is going to take a little getting used to. My colleges keep snickering at me. It has something to do with the audible sound I make when frustration sets in. "Oh but this is so easy with ant, what evil is this msbuild trying to foist on us", "This would be so much easier in Eclipse".

It's the little things. I want to copy a file and replace a string within it. A simple template replacement process or in java terms, ant copy filter. NAnt doesn't support it either so I feel the need to learn msbuild.

So I have a fred.msbuild file but you open it in VS and it gives you schema errors on all the property tags because msbuild uses the tag name as the property name. So where is the MSBuild editor? MS makes everything a dialog and thats too hard for build scripts. I just need an editor.

The script can now "Copy" a template file, then "FileUpdate" is to do string replaces in it. Oh I have a lot to learn.

I fully expect to be assimilated in another few weeks and will start extolling the beauty of this new world. Until then, it is painful while the new gadgets are being surgically implanted into my brain.

I am looking forward to the new C# language features.

4/29/2007

Sieve of Eratosthenes - After thoughts

The most interesting part of this exercise was that each attempt performed better and better until I the DSL version. Even the objectisizing and then groovyizing resulted in better response times. Now perhaps I doing something silly in the DSL version because the extra method dispatch for the DSL keywords shouldn't slow it down 5 times.

It is clear that the need to use a DSL for this problem is irrational.

Here are the tests for the Sieve of Eratosthenes problems and the results

.Time: 488.8ms: Algorithm: Sieve1 Primes: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
.Time: 248.4ms: Algorithm: Sieve2 Primes: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
.Time: 270.4ms: Algorithm: Sieve3 Primes: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
.Time: 1145.6ms: Algorithm: Sieve5 Primes: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

Sieve of Eratosthenes - Try 4 - DSL

Now to re-describe the basic parts of the algorithm into domain terms. Not saying its better just cooler.

Sieve of Eratosthenes - Try 3 - Groovyize

How about those groovy categories, the really allow you to put the code in the place you want it. Note I didn't say the right place?

Sieve of Eratosthenes - Try 2 - Objectize

Add in some OO, not much, just a sprinkling.

Sieve of Eratosthenes - Try 1

The groovy quiz this week was a prime number problem and I evolved through 4 different solutions.

The first was the basic script style approach, the second used OO, the third was groovyized with categories and the last converts the whole thing into a DSL. DSLs are cool right?

I am going to let each unfold in different posts so that you can compare and contrast if you are interested.

Here is the first, the basic "Sieve of Eratosthenes"

4/12/2007

A groovy finite state machine

Well this is my first DSL. The people on the groovy users list are talking about trying to model something like this from the ruby example posted.

Sing: "Anything they can do, we can do better, or at least as well."

4/10/2007

"Language Meshing" - April 10, 2007

I have created a new term, "Language Meshing" that refers to the ability to mix difference languages within the same source file.

Not a new concept I know, but I like the term so am blogging it now. Yes I might have created something completely new and completely useless.

I was review what Charles Nutter was posting about for JRuby and found their use of the Java 6 scripting extensions.

http://headius.blogspot.com/2007/03/can-your-ruby-do-this.html

I now dub it "Language Meshing". It might catch on.

4/09/2007

WheresTheWater


WheresTheWater
Originally uploaded by esumerfd.

2/27/2007

Leadership, the conflict

I thought I would comment on the problem of leadership because there are so many opinions and so many books, why not another little blog entry in the world of words.

Always gentle
Always decisive
Always open

I came up with these tenants, intentionally conflicting, to convey the personality profile of a leader. No leader can always be one or the other, the best leaders know when to switch and how to blend these ideas.

A team member presents an idea. The leader shows openness to listen and understand, then they have to switch, do they go to decisive to accept the idea and drive an action into the plan or to gently to discuss the idea until the team member sees its flaws.

It's never that simple though, a situation that distracts the team from a goal may require closed, firm, decisiveness. A good leader can be resolute and confident as opposed to closed and gentle.

Word games, yes, but these are the gray areas of human emotion, none of them absolutes, so a leader has to monitor guidelines and feel their way towards goals.

Your leadership goals might include, "be respected", "be approachable" or "I will always listen". Does this sound like a love fest? It's not a leaders goal to be liked but it helps. Leaders drive to a goal, the doors they break on the way are the tinder of their fire. This can conflict with being liked.

Your leadership goals might include more practical concepts like "will achieve goal within time line" or "maintain high customer rating". There is a cold, unemotional side to leadership that can help drive success but can loose some of the moral boundaries that we live by. Who should you fire when the budget is tight? When do you give up on the unteachable underachiever?

These are the sides of this game that I have the most difficulty with. I have always loved the teaching, mentoring and guiding parts of this job. I don't mind playing the motivational games to get more investment from a team. I do have a really hard time with knowing the right time and technique to cut.

I have a lot to learn about being a leader.

2/02/2007

Two New Coding Mantras

What we tell ourselves drives what we are. A simple psychobabble statement. To a developer this drives what we produce.

Are you won't to say "that is good enough" or "sure that will work".

Or are you more likely to ask yourself "is this the best approach?" or "what would happen if we tried this alternative?".

Certainly, time and pressures push us back and forth between these attitudes so this isn't driven by personality alone but also represents an assessment of your personal priorities.

While reviewing code today I noticed two symptoms that represents trends of focus that the developer needed to address.

The first was the attention attributed to which class file they were typed their code in. Every word we type has a domain relevance that should force us to consider its appropriateness in the class we are editing.

The second is the tendency to think in instances instead of across time. The code I write today works today but will it work tomorrow or in another situation or environment. This actually occurred in a test for proving a date manipulation method worked and the test only worked yesterday.

So, from these two observations I decided I needed to more mantras to add to my preaching.

Every word in the correct class.

All tests work always.

They could probably be made a little more succinct and perhaps the second shouldn't be test specific but "that is good enough".

1/01/2007

Firefox and Skype Integration

I recently got back into using Skype to chat with my family in the UK and with the upgrade I was asked to install a new Firefox extension. This extension scans all the pages that you browse looking for phone numbers. When it finds them it converts them into Skype protocol call links.


Combine this with the new Skype free calls anywhere within the US and you get the easiest way to integrate voice into the web.

11/15/2006

Upgrade Blogger Version

Hope this upgrade doesn't cause anyone any problems :) They have a nicer templating editing feature and some better default templates than I can create.

4/04/2006

The Emotional Side of Design

Design sessions can often become emotional but this is not what I am talking about. People have strong feelings about the right and wrong way to do things but this is not what I want to address.

I want to try to describe the emotional feelings that one gets when a design idea is proposed. These aren't the strong passions of right or wrong but more of a gentle tickle deep inside that something is wrong.

We have all read articles on the "art" of programming and design. We have seen and experienced the best designers become the worst teachers. There is much written on the levels of knowledge from:


  1. I don't know how much I don't know.
  2. I have studied the process and am comfortable with it.
  3. This process is crap and these are the improvements we need to make.
  4. I understand thing well enough that I can explain it in simple terms.


we all exist at all levels. On many computing subjects I have no clue how ignorant I am and on others I teach.

I experienced a level 3 yesterday that went something like this:


Ed: Yes, you should replace VSS with CVS.

Customer: But CVS can't do file linking across branches. We only want to have to make a change once for all the product branches.

Ed: While that sounds like an advantage, it is actually the most horrific situation you could possible create for yourself.


I don't think I conveyed this statement quite as strongly as I might have but I couldn't articulate why file level release versioning was such a bad idea. I explained how I would manage it with branch and merge techniques in CVS and I think they saw this as a possible alternative but I didn't have the knowledge necessary to explain that the process they were using was exactly the thing that was killing their development throughput.

They gave me some hints to their atrocities, "We make developers send emails to the configuration team to check in and out files" and "The last release is managed on the O: drive because it was too difficult to manage in VSS".

Perhaps I could have got into the mathematics of why X files with Y differences takes Z brain hours to manage and the slope of the graph looks more like Everest than a manageable process.

So what is this emotional link we get with a set of ideas. Perhaps emotional is the wrong word, is it a 6th sense, intuition or perhaps just random gas.

Anyway, I have no answers, just experiences.

3/22/2006

Site Integration - Maps, Music, Chat and Sound

Site Integration - Maps, Music, Chat and Sound

I have been playing with techniques for site integration for a little while and have some interesting samples that are worth cataloging.

We all know that Web Services and B2B are the primary architectural vehicles for integrating computer systems but its not what is visible in the real world. Certainly we are building web services and certainly they serve to integrate systems but to the internet culture as a whole they are an irrelevance.

Let me say it this way. Corporations use B2B techniques to seamlessly integrate symbiotic features. Web Site builders use other techniques to integrate user experiences.

Perhaps we could look at the two as layers of the same cake. An internet user experiences features presented to them. Some of those features might require Web Services to achieve their goal but the user integration of experiences is a "higher" level integration.

Ok, so I can't explain it. Lets go with some examples. These are all on my home page.

Frapper



Frappr allows us to share graphical locations and present them as a map. A piece of this map can be integrated onto your web site. The XP Cincinnati site integrated this information into a blog entry.

They use simple javascript to link the two sites together.

Odeo Blogging



Odeo has developed a technology that allows us to record sound and publish that sound. Most use it for blogging but I have heard that some are using it to record and publish their music as well.

I have an Odeo blog and this allows me to record snippets of sound and then integrate that sound into my web site.

In this case the integration is achieved with an object tag that runs a some flash. The parameters point to the recorded mp3 that is stored on the Odeo site.

last.fm Music Listening



last.fm is a music tracking site. It supplies you with plugins for winamp, Media Player and others that will send the name of the music you are playing to their site. This can then be retrieved in a variety of formats to your website so that your customers can see what music you are playing at that moment.

This uses a little pseudo javascript insert that retrieves the HTML necessary to list your music.

Instant Messaging or Instant Talk



There are lots of features that allow you to publish your Instant Message online status to your web site but I was focusing on Skype since it includes the voice and video features that will ultimately become part of the communication applications of the future.

This site uses a little javascript with a new embedded protocol "skype:" so if you have an anchor with "skype:Edward Sumerfield?call" in it and you have the skype client installed then clicking on it will call me.

Conclusion


I think this point has been made in other blogs already but it doesn't hurt repeating. The primary site integration tool is javascript since it is the glue code that allows countless disparate technologies to interact.

If you are developing any kind of user interface tool today. Make very sure that you are including your javscript hooks. It will allow your tool to become integrated in ways that you can not imagine.

3/02/2006

Agile Set Me Free

My current client is thinking about adopting a more Agile approach to software development. We have had initial discussions and passed out books to read. We have been running an XP project for them for 6 months so they have all witnessed its success.

Someone found an article written in July 2002 that goes to town discrediting XP. So, I need to spend time trying to understand this 4 your old paper and trying to explain where it is misunderstanding the Agile proposals.

This is when it hit me. All the comments the author makes fall into one category. Fear. Fear of change. Fear that iterations make projects unmanageable. Fear that less documentation will cripple the maintenance effort. Fear that Test Driven Development will not produce a perfect object model. All of the answers stem from the base feelings that we have developed over years of working with requirements that changed and software that we kept on finding bugs in. We have beaten ourselves up so much about how little discipline we have and how bad we are at talking to the customer that we can't imagine that the opposite approach might be better. We are just not good enough to execute the perfect process we have been working at all these years.

All the complaints I read about Agile take everything it says at face value and fail to see the depth that it is suggesting. Release early is miss-read as ignore requirements. Allow the customer to change requirements is miss-read as never knowing what you are about to release. Don't write irrelevant documentation is immediately the terrifying idea that there will be no documentation.

So much confusion from simple, practical improvements in a process.

Agile is a liberation of our freedom to produce great software. Agile is a reconnecting with the essence that is writing software to solve business problems. Agile gives us the excuse to succeed when all we had before was more disappointed customers and another bug to fix.

Dam this job could be depressing. I have always loved programming but hated the job. It never made any sense until Agile opened my eyes. Actually, to be more specific, Mark Windholts opened my eyes when he pitched the test first practice to CinJug. Dude, you rock.

2/26/2006

Another Hour Another Rails Release

While I am a complete novice at this and my controller tests still don't work I have been able to add basic delete and create functionality to "WebZone On Rails" in about 5 hours.

The reason I couldn't do this in Java is because of ActiveRecord and the tight integration between the controller and the page.

With ActiveRecord I have been able to create and delete from an existing MySQL schema with just a couple of lines of code. With the integrated mock data infrastructure that comes with Rails I have full unit tests for all these steps.

With the tight integration of controller and page I am able to create controller instance variables and directly reference them from the rhtml pages. This makes it mind blowingly easy to load data and reference that data directly on the page while maintaining the MVC isolation. This is similar in concept to the .Net idea of the page and code behind being the same instance.

I still can't run my controller tests. Ran the gem update rails with no improvement.

Blog Entry From Camera Phone

Trying the mobile blogging feature at blogger.com. Just have to send an email to go@blogger.com and 'they do the rest'. Sound too easy.

Publishing Rails with SwitchTower

I need a simpler way to get my changes out to the web site. currently I am just copying file by file to FTP but this is tedious and error prone. I have heard that Switch Tower is the tool of choice for deploying Rails apps so here goes:


gem install switchtower


The install seemed to go well with the following dependencies also being installed.


Attempting local installation of 'switchtower'
Local gem file not found: switchtower*.gem
Attempting remote installation of 'switchtower'
Updating Gem source index for: http://gems.rubyforge.org
Install required dependency net-ssh? [Yn] y
Install required dependency needle? [Yn] y
Install required dependency net-sftp? [Yn] y
Successfully installed switchtower, version 1.0.1


Switch Tower needs to make some changes to the current rails app so that it can deploy it.


switchtower --apply-to [full path to rails app]


This seems easy enough but the first run gives me this. After a hour of google searching and drilling down into the gem install I find that the error, is infact, correct, the rails_generator/sripts/generate code does not exist as part if the switchtower install but I don't know where to get it so I am stuck.


d:/products/ruby-1.8.2-14/lib/ruby/site_ruby/1.8/rubygems/loadpath_manager.rb:5:
in `require__': No such file to load -- rails_generator/scripts/generate (Missin
gSourceFile)
from d:/products/ruby-1.8.2-14/lib/ruby/site_ruby/1.8/rubygems/loadpath_
manager.rb:5:in `require'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/activesupport-1.2.
5/lib/active_support/dependencies.rb:214:in `require'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/switchtower-1.0.1/
lib/switchtower/generators/rails/loader.rb:7:in `load!'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/switchtower-1.0.1/
lib/switchtower/cli.rb:248:in `execute_apply_to!'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/switchtower-1.0.1/
lib/switchtower/cli.rb:219:in `execute!'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/switchtower-1.0.1/
lib/switchtower/cli.rb:12:in `execute!'
from d:/products/ruby-1.8.2-14/lib/ruby/gems/1.8/gems/switchtower-1.0.1/
bin/switchtower:11
from d:/products/ruby-1.8.2-14/bin/switchtower:19:in `load'
from d:/products/ruby-1.8.2-14/bin/switchtower:19

WebZone port to Rails

I have been using a product called WebZone since 2001. I built it to do what I want and have extended for me. It supports other users and sharing data with them but primarily it has always been for me.

Its primary goal is to allow me to collect information in one place and organize it. It does this with good support for drag and drop into the browser, JavaScript scriptlets that can add the current page to your WebZone account and the ability drag your information around your WebZone to relate it in anyway that you want.

WebZone on Java



At 5 years old it needs some serious re-writing. When I started it I was just getting into test first so it doesn't have many tests. It has no mock data so continuous testing is out.

Since Rails is getting so much press I have decided to try it our there.

Phase One. Allow a rails app to read and navigate a WebZone database.

Phase Two. Add edit feature.

Phase Three. Add delete feature.

Phase Four. Add create feature.

We are in Phase three and it is now deployed to

WebZone on Rails



So far so good.

The basic app was easy to create but I needed some ActiveRecord help from the XP Cincinnati team to get the database interface working nicely. Thanks to Jim Weirich.

With that part working, putting the rhtml files together to display the data was a snap.

A continuing problem is getting the controller tests working. So I am doing as much unit testing as possible but not being able to test the controller level is a serious problem. I am getting the error:


Exception: No url can be generated for the hash
{:targetId=>"1", :controller=>"read", :action=>"item", :targetType=>"TableText"}
generated_code/routing/generation.rb:5:in `generate_default_path'
.../action_controller/routing.rb:419:in `send'
.../action_controller/routing.rb:419:in `generate_path'
.../action_controller/routing.rb:415:in `generate'
.../action_controller/routing.rb:602:in `extra_keys'
.../action_controller/test_process.rb:86:in `assign_parameters'
.../action_controller/test_process.rb:295:in `process'
.../action_controller/test_process.rb:307:in `get'
webzone3/test/functional/read_controller_test.rb:20:in `test_item'

12/28/2005

Java Closure Chaining

I am playing with closures in java. Not as simple as the Ruby counter parts but a benefit to our programming arsenal I think.

I have come to realize two new things from this experience.

Testability

Compare


Iterator iter = list.iterator();
while (iter.hasNext())
{
A a = (A)iter.next();
do something
}

With

ListTools.each(list, new ClosureObject()
{
public void call(Object a_object)
{
A a = (A)a_object;
do something
}
});

How many pre-bugs do you see in each version. Both have 4 lines of code but the first requires 3 dot references which adds opportunities for those methods to do something unexpected.

Because of the the "final" requirement in java I found this construct to be a rarity. Instead we need something like this.

ListItemMunger munger = new ListItemMunger();
ListTools.each(list, munger);
System.out.println(munger.something());

class ListItemMunger implements ClosureObject()
{
public void call(Object a_object)
{
A a = (A)a_object;
do something
}
});

The most significant benefit with using Closures in java is that the loop-core is removed and is more testable than ever before.

public void testLoopCore()
{
ListItemMunger munger = new ListItemMunger();
munger.call(new SomeObject());
munger.call(new SomeObject());
munger.call(new SomeObject());
assertTrue(munger.something());
}

Now that I have classes that scan directories recursively, scan the files within them and then the line of text within each file this testability feature has been invaluable.

Closure Chaining

So I can scan directories, files and lines within files. How do I do that with these closure things.

DirectoryRecurseLookup.each("my path", new ClosureFile()
{
public void call(File a_directory)
{
FileLookup.each(a_directory, new ClosureFile()
{
public void call(File a_file)
{
StreamLineLookup.each(a_file, new ClosureIntString()
{
public void call(int a_lineNumber, String a_line)
{
System.out.println(a_lineNumber + " : " + a_line);
}
}
}
}
}
});


Well that's a lot of nesting but relatively simple syntacticly, no pre-bugs waiting to pop out at me. My first version took each of the closures into a separate class to simplify the code and make it more testable and it all worked fine.

Then I realized what I was doing wrong. I am just chaining closures so why can't the closures encapsulate that.

StreamLineLookup lineScanner = new StreamLineLookup();
FileLookup fileScanner = new FileLookup(lineScanner);
DirectoryRecurseLookup dirScanner = new DirectoryRecurseLookup(fileScanner);

DirectoryRecurseLookup.each("my path", dirScanner);

So as an example:

class DirecotryRecurseLookup implements ClosureFile
{
public static each(String a_path, ClosureFile a_closure)
{
// find files and pass them to the closure
}

private ClosureFile m_closure;
public DirectoryRecurseLookup(ClosureFile a_closure)
{
m_closure = a_closure;
}

public void call(File a_directory)
{
each(a_directory, m_closure);
}
}

10/27/2005

XP Cincinnati - Frappr

I am probably late to the party but this Frappr idea rocks. I created a frappr map for XP Cincinnati to see if we can get an idea of how spreadout we are.

Frappr XP Cincinnati

9/07/2005

Pre-bug - Variable Notation

A prebug, is a piece of code that is about to become a bug.

This is much like Martin Fowler's code smells (http://www.martinfowler.com/books.html#refactoring) but his writing comes from the perspective of how to find and recognize bad code and refactor it to improve it. The pre-bug concept is more like patterns for defensive coding strategies.

I coined the phrase prebug to describe code that you are typing in that will very soon be re-classified as a bug. Hopefully the test turns your prebug into a bug by failing but what if you can work out a way to type in your code that will prevent you from entering pre-bugs in the first place.

For example, one of the old C bugs that was so common was the single-equal-if problem.


if (a = 1) { printf("I think its one but who really knows"); }

For those unfamiliar with C, this statement would assign 1 to a and return true, always.

As a developer is typing in this code they may not be considering the possible bugs they are generating. So what if we retrained ourselves to always type this.

if (1 = a) { printf(("I know its one"); }

In this case the compiler will thrown an error saying that you can not assign a to the constant 1. What we have done here is slightly change the way we type in code and avoided a nasty bug from passing on down the development stream, potentially to production.

Here is another prebug idea that I want you to suggest solutions for. How would you enter this code to reduce the likelihood of the bug getting passed your ever vigilant eyes?

class Counter extends Thread
{
private static int counter = 0;
public void run()
{
while (counter < 10)
{
counter++;
doSomething();
}
}
}

The bug is that the counter is static and is able to run inside a thread, clealey a problem in this case. The same problem can occur with any static variable even its not so obviously in a class intended for multi-threaded operation.

The best solution I have found for spotting this kind of bug as I am entering it is to classify the variable names by scope and lifetime. We have all seem these notations in coding standards docs for years but I think the application of these ideas for the specific purpose of preventing bugs is not so commonly realized.

The java prefixes I use for these problems are:

statics: s_
instance: m_
arguments: a_

With the statics, instance and argument variables clearly identify to the reading eye what the scope of the variables are. The previous code should be entered like this.

class Counter extends Thread
{
private static int s_counter = 0;
public void run()
{
while (s_counter < 10)
{
s_counter++;
doSomething();
}
}
}

Eclipse offers auto-prefixing so all of its code generation features work once you have configured these notations.

8/23/2005

Emailing to a Blog

This is an experiment to see if this is a worth while feature. I am a little concerned that I will want to post too much crap. The editing process is important and slowing my posting down to 1 or so a month keeps things sane.
 
Anyway, one can but try the new processes and see what happens.
 

3/29/2005

Decoupled UI

My original question:

I want to be able to do this but it will not compile because the EventHandler does not have a no arg constructor.


IDictionary collection = new Hashtable();
collection.Add("myevent", new EventHandler());

A single event has the syntactic oddities

event EventHandler fred;
fred += new EventHandler(this.SomeMethod);
fred("x", eventArgs);

So how do I add fred to a collection so that I can do this
collection["myevent"] += new EventHandler(this.SomeMethod);


The answer:

I found the answer so here it is. Thanks to Mike Wood for his expertise.

The first and simple answer is that you can't do what I was asking. Events can't be constructed in the way that we would expect so can not be stored in a hashtable.

Background

The new information that I learned was about multicast delegates. These are the normal delegates that are created for us in our WinForms apps but they actually have the ability to store more than one callback.

It turns out that an event is completely unnecessary when declaring a callback. MSDN says that its just a safer syntactic representation of a multicast delegate (An Event to Remember).
delegate void MyCallback();
MyCallback fred;
fred += new MyCallback(this.SomeMethod);
This will fail to compile because fred is not assigned and you should not += to it.
delegate void MyCallback();
MyCallback fred;

fred = new MyCallback(this.SomeMethod);
fred += new MyCallback(this.SomeMethod);
This will work because fred is first assigned with a delegate and then one more is added. Note that we can not re-assign a callback to the delegate to clear all existing delegates. This is the danger of the delegate syntax. This is now a multi-cast delegate since fred contains multiple callbacks that can all be invoked in turn by:
fred();
So the alternate syntax allows for the += in any situation. By placing the keyword "event" in front of your delegate declaration you allow the += to always work. This doesn't prevent you from doing an assignment so its not much protection but it does mean that whenever you see an assignment to an event you should be suspicious.
delegate void MyCallback();
event MyCallback fred;
fred += new MyCallback(this.SomeMethod);

Problem

What I wanted was a single class that could manage a set of delegates, categorized by data type, that could be subscribed to and published from different areas of your code to ensure that there was no compile time coupling between them.

Example of the problem:

class A
{
private B b;

public A()
{
b = new B();
}

public OnButtonPressed()
{
b.MakeBread();
}
}

class B
{
public MakeBread()
{
Console.Write("rise rise rise");
}
}

Notice how A has a reference to B. This means that when I want C to do something when the ButtonPressed event occurs I have to edit A to add a new reference. Also, If I want to add another layer between A and B then I have to change A to make the new reference and move the B reference into the new location. Lots of code changing is bad from a maintenance and testing perspective.

Design principle. Open Close Principle

"Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification."

C2 Wiki - OpenClosedPrinciple

In this example I had to change lots of existing code to rearrange my structure. This is very common in UI applications as you move the UI around the elements of the UI have to be moved between source files and the call backs have to be moved as well.

Solution

The solution to the original problem is to put a delegate in the hashtable and then add additional delegates to the same element. No events were used during the making of this code.

I wrapped this in a class called PubSub with two static methods Subscribe and Publish (Download Solution)

Example:

class A
{
public A()
{
}

public OnButtonPressed()
{
PubSub.Publish(new UiEventButtonPressed());
}
}

class B
{
public B()
{
PubSub.Subscribe(typeof(UiEventButtonPressed), new EventHandler(MakeBread));
}

public MakeBread(object sender, EventArgs args)
{
Console.Write("rise rise rise");
}
}

Notice now that class A doesn't know who is reacting to the ButtonPressed event, all its doing it notifying the world that something happened. Class B on the other hand is a simple standalone class that knows it has to do something when the button is pressed so subscribes for that event.

I could now write a class C that subscribed for the same event without changing any existing code at all. This is a massive maintenance and test advantage. Imagine being able to extend an existing system by dropping a new dll into the deployment. Sweetness.

This type of abstraction also offers extension advantages. Imagine the day when your UI gets so slow that you have to start backgrounding some of the actions. You can add extend your PubSub class to submit all the callbacks on background threads.

What about the idea of distributing your application. Say you want a background service to manage the synchronization of data from your UI to some external storage. You could extend PubSub to post events across process or machine boundaries and plug into your existing application without changing it.

Obviously, I am simplifying this a little but the abstractions are the key to making your system flexible enough to be tolerant of these kinds of changes.

2/18/2005

CinDnug 2-20-05

Doug Rohrer, of Avanade Inc employ, presented an overview of the Microsoft Enterprise Library (entlib).

Apparently Avanade are the original writers of these libraries as the copyright at the top of the source indicates. Oh did I mention that we get the source? The license allows you to modify for your own use but you can not redistribute your alternations and you must leave any existing copyright notice at the top if you do not change the code.


// Copyright © Microsoft Corporation. All rights reserved.
// Adapted from ACA.NET with permission from Avanade Inc.
// ACA.NET copyright © Avanade Inc. All rights reserved.

This is a library of "application blocks" that are intended to help developers with the basic plumbing of an application. A block is just a subset of a library which is akin to an assembly. In java terms its just a jar. I don't know why "block" replaced "library".

Doug writes about the entlib in his blog.

Doug Rohrer's Blog

Download it here after some registration steps:

Microsoft Enterprise Library

I am afraid that I arrived 30 minutes late so missed a couple of the initial block descriptions but the website doc is good. These are the blocks in the entlib

o Configuration Application Block
o Data Access Application Block
o Caching Application Block
o Exception Handling Application Block
o Logging & Instrumentation Application Block
o Cryptography Application Block
o Security Application Block

One the most interesting features of this library is that it comes with source. When you download it you get a selfextracting exe that unloads the source to your disk and, with compile checkbox checked, proceeds to compile the library in place. Having the source available makes this a far more valuable resource since we can not only use it but also learn from the code.

All the libraries use the Configuration block and most use the Logging block so there is a good synergy between them all. They all have good factory abstractions so its simple to replace the various providers with your own implementations. Each folder in the source contains a Test directory where NUnit tests sit.

Here is a simple sample of each.

Logging:

    Logger.Write("My message", "someMessageCategory");
Each write can optionally, specify a category that can be configured in the configuration file and drives where the message is written to.

There is no method level distinction between error, warning, info and debug messages. There is also no class level message filtering. You could use the category names for either but not both.

This being a class level API, instead of instance level, its flexibility is limited. A simple improvement would be to allow us to create our own reference to the logger and then we can choose to make it an instance or static property.

So, compared to Log4Net (http://logging.apache.org/log4net/), this solution is not adequate.

Configuration:

    settings = (MySettingsType)ConfigurationContext.GetConfiguration("section name");
settings.MyProperty
The advantage of this package over the built-in App.config is that you can select the storage type. This seems like a good solution for .Net app config loading.

Data Access:

     myDataSet = DatabaseFactory.CreateDatabase("Sales").
ExecuteDataSet("GetOrdersByCustomer", myCustomerId );
I missed the comments on this one but the code snippet looks simple enough. I asked Doug after the presentation about support for Transactions but he didn't have any concrete information.

Longer term I am more interested in libraries like NHibernate (http://nhibernate.sourceforge.net/) that support a full Object/Relational mapping solution. Then you can look into Spring for .Net (http://sourceforge.net/projects/springnet/) and abstract your transaction management out of your code completely.

Caching:

    factory = new CacheManagerFactory(Context);
cacheMgr = factory.GetCacheManager("SmallInMemoryPersistence");

cacheMgr.Add("key", "cache");
cacheMgr.Remove("key");

cacheMgr.Dispose();
The location of a cache can be configured as in-memory or in-database so it can be used within a clustered environment. It supports various cache ageing algorithms that allow you to control how stale you data gets.

I am unsure about this library. With a IDictionary type interface you are limited in the types of data that you can cache. Not that you can't store anything but that you can't get it back as easily. Say I wanted to store a row from a dataset, what would I use for a key? It would have to be the unique key to the row but if that is a compound key I would have to come up with a string representation of that information.

I am sure that there are some good uses this library can be put to but with caching being such a complex layer I am not sure that it is flexible enough for the more complex applications.

Exception Handling:

    catch (Exception ex)
{
bool shouldRethrow = ExceptionPolicy.HandleException(ex, "policyname");
if (shouldRethrow)
{
throw ex;
}
}
The goal here is to centralize the processing from all our catch blocks. The HandleException method reads configuration where a set of exception handlers are configured. You can relate a list of handlers to a policyname that can log, write to the event log or add you own custom handler.

The biggest downside to this approach is that you loose all your context logging. Most exception handlers are going to format a message that includes information from the local context that will help debug the problem. The only way I can see to add this feature and still use this exception handler is to wrap the thrown exception in your own exception and pass that in.
        MyException mx = new MyException(ex, "Context specific message");   
bool shouldRethrow = ExceptionPolicy.HandleException(mx, "policyname");
I question whether the function that I want to perform in my exception handlers should be abstracted to the configuration file level. Certainly, common code should be extracted into some application specific class but to standardize that and push it all the way to a config file seems unnecessary and not very useful.

Crypto:

    Cryptographer.EncryptSymmetric("dpapiSymmetric1", "plain text");
Cryptographer.DecryptSymmetric("dpapiSymmetric1", encrypted,);

Cryptographer.CreateHash(hashInstance, plainTextString);
Doug also demoed encrypting with sha1 and it was as simple. This is going to be really easy and will, hopefully, ensure that every programmer gets comfortable with this subject matter and uses it. There is way too much data out there that is not secure because the average programmer doesn't know how to use the cryptography api.

Security:

    factory = new AuthenticationProviderFactory();
IAuthenticationProvider provider = factory.GetAuthenticationProvider();

if (provider.Authenticate(new NamePasswordCredential("Fred", "password"), out identity))
{
// Woohoo
}

factory = new AuthorizationProviderFactory();
provider = factory.GetAuthorizationProvider();

if (provider.Authorize(principle, context))
{
// Woohoo
}
A simple authorization and authentication abstraction that will simplify your login pages and access checks in your code. You can plug in your own providers and perform application specific checks as needed.

Conclusion:

Some of these seem to be very useful libraries that I expect to start using in my current project.

A possible improvement that could be made to the distribution would be to formalize the mock classes that are used. The "Test" folders are full of mock classes that help prove that various pieces of functionality work. When I am testing my code I will have to concoct some mock configuration to drive the various paths though my code. If the library supplied some mock implementations it would save me from writing my own.

Thanks Doug for a great presentation.

2/11/2005

Cold basement

My office is in my basement. Yes, a little corner of a cold dark hole in the ground. Winter makes it intensley cold with one electric heater making my body hot on one side and leaving the other blue.

Still, it beats trecking through the snow to a small dark cube.

Cincinnati doesn't get too cold in the winter, not compared to the more northern areas. However, this is my home and that gives me the right to whine about it a little.

The view from our back window is nice after a fresh snow. The last snow was windless so produced some excellent depth on the individual branches.



2/06/2005

Referencing EXE assemblies in VS.net

The problem, as discussed in the CinDnug use group, was that a VS.net project that contains tests can not reference a project that generates an exe. The only design solution is to make the exe code a one liner that calls a main dll but this has quite an impact on other design decisions.

When you try to add a reference from a dll project to an exe project in VS.net you get a warnings stating that the reference target has to be a dll. You can solve this problem with some judicious editing of your .csproj file.

Editing your .csproj file will show references declared like this


<Reference
Name = "ProtoTabBack"
Project = "{6292AE62-0514-40F7-99C0-C2C181BF9A15}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "TabulatorFront"
AssemblyName = "TabulatorFront"
HintPath = "..\TabulatorFront\bin\debug\TabulatorFront.exe"
/>

Note there are two types of declarations here. The first type uses the package project guid that you can find in your .sln file in the following format. The first guid is the Package and the second the Project.

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TabulatorFront",
"TabulatorFront\TabulatorFront.csproj",
"{DD6F402B-1823-489F-AC6C-B9B8FE18391D}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject

Using this "project reference" in your .csproj file results in VS.net flagging the reference with a little yellow triangle and saying that it has to be a .dll file.

However, using the second Reference format and referring to the exe file directly works. I am now able to code to and link my tests with the exe project code, utilize existing test infrastructure to write tests against UI code and keep my test code out of my production deployments.

Thanks James for the suggestion.

2/03/2005

Robust code

Trying to get people to stop hard coding expected results in tests is not easy.


IList rowList = db.GetSomeRows()
Assert.Equals(4, rowList.Count);

EEEEEEkkkkkkk

Code is like poetry
blowing in the wind,
beaten from left and right
crashed and regularly skinned,
choose the best of parchment
to ward against the eternal din.

1/19/2005

Recap CinNug meeting 1/18/2005

CinNug - http://www.cinnug.com/.

This was a Microsoft product pitch for Team System by Alex Lowe who runs with the title Developer Evangelist. He made a point of apologizing for his title at the beginning.

To be released in the second half of the year sometime, this solution includes a Team Server and three possible client options, Team Architect, Team Developer and Team Test. Each offers extensions to Visual Studio 2005 which is due for release in the middle of the year.

The target market is the enterprise development team so cost will be high. Alex kept comparing it with the Rational target market. He mentioned that MS would beat their price by 20% but that we should not do a feature for feature comparison since they are very different products. MSDN Universal owners will have a license for one of the three client options but would have to by Team Server anyway. It is not clear which of the client features require Team Server to operate.

The idea behind this solution is to establish a standard framework from which teams can manage their projects. Apparently MS is starting to use the product internally but so little of it is working at the moment there is little internal feedback. It is their intention to completely adopt this development framework within the next 5 years.

Disclaimer 1: I have never used Whidbey or Team System so this write-up is probably filled with assumptions. I am copying Alex so he can correct us if he feels like it.

Disclaimer 2: I am also a long time java developer with perhaps 4 months of full time .Net work under my belt so please forgive any ignorance based bias. With years of VC++ and ASP development I have some background but java swept me off my feet many years ago.

So into the new features of Team System.

Team Architect contains a design diagramming tool replacing the use of Visio for class diagrams. Alex talked about the MS's preference for Domain Specific Languages (DSL) as opposed to the standards based UML syntax. He explained that customers are more likely to understand a language that uses the terms and shapes that they are familiar with.

The demo included a class diagram which showed up in non-UML format. Though we only saw two classes, one that inherited from the other, the inheritance arrow was UML like but the class boxes had rounded corners and contained non-UML sections and verbiage. I am all in favor of DSL's when they best represent the subject you are communicating but developers understand classes and I would wager most understand or at least have seen UML so why go non-standard for class diagrams?

The class diagramming tool included two way dynamic code synchronization so we you add to your diagram the code is being written and as you edit your code the diagram is being updated.

To my mind the biggest problem with class diagrams of larger systems is complexity so the selling points of a class diagramming tool should be the filters that can be applied to simplify the representation. Unfortunately we didn't see any of that.

Enhancements to VSS improve performance, scalability and offer new features like "shelving" which allows you to check your code into a new branch so that you don't pollute the main branch with your failing tests until you are ready. Since VSS already supported branching I assume all they have done is to make it easier to do and given it a fancy name.

Most significant improvement to VSS is that you can integrate with it remotely over HTTP so it can finally be used outside a LAN. While I love CVS, it would be better if we could use a source control system that integrated into VS.

Alex presented the unit test features that allow you to select the classes and methods to create tests for. Team Developer produced NUnit like code to exercise them. Not just test stubs but completed methods with some best guess code in them. This months .Net Developers Journal discusses the same feature with the similar screen shots in Whidbey which will be Visual Studio 2005 so I presume that there is some overlap in these products.

Notice I said "NUnit like". Microsoft has changed the "attributes" that you use to tag the classes and methods that are exercised as tests. NUnit uses "TestFixture" and "Test" but the new MS unit test integration uses "TestClass" and "TestMethod". I view this as a change in standard names that are out in the industry and is completely untenable.

Imagine a 100 developer team with 1000's of NUnit tests thinking about migrating to VS.Net 2005. I would lay money of the fact that no admin is going upgrade 100 developer machines in a weekend, the risk would be enormous. So as desktops are upgraded they become unable to run the product test suite. Alex mentioned that a tool would be provided to convert all your existing test cases but you are still leaving a portion of your developer community out of the testing process until they migration is complete.

Code attributes were invented as a way to abstract the code location from class and method names. This can be a fine idea if one wants that abstraction. MS has ignored the industry standard names and is forcing developer shops to build repositories of tests that are dependent on Microsoft testing tools. Choosing to use these new unit test tools is as bad an idea as choosing .Net as a cross platform development strategy. I see myself continuing to use TestDriven as my VS integrated NUnit framework.

The demonstration of test automation went pretty smoothly but I missed asking one question. When Alex entered into the test creation steps a new VS like window opened up with a new view layout targeted on test management, I believe Alex even called it a "Test Manager". From this new "Test Manager" Alex was able to run the tests and we saw the sample test being scheduled, we waited a little and then it was in run state and finally the red/green bar appeared. Alex then exited this new window to get back to the code.

This UI will impact the way test first developers work because it introduces a time and complexity barrier between your fingers in the code and the red/green bar of feedback. This will reduce the number of times tests get run which is contrary to the goals of test first development.

One of the major reasons that JUnit, NUnit and all the other XUnit frameworks work so well is that they are ultra simple to use. With IDE integration the single click to run a test is a really important feature. I think MS missed the boat on this one.

---------------------------------
By the way Alex, you mentioned that test first required writing tests before the code. You should rephrase that as "writing the tests while writing the code". The process requires that a single, simple test is written before code is written and when the test passes, another is written. Think really small cycles like 60 seconds or so.
---------------------------------

Team System has an integrated build and deploy process. Not much was said about it but a short demo showed the creation of a diagram that you can add IIS server definitions to, then you can drag your Web Projects into your diagram to deploy them.

Since best practice suggests isolating your build and deploy tools from your IDE this may not be a good solution. However, I didn't ask the question, and Alex didn't say whether the build/deploy tools could or could not be used from outside the IDE or whether an IDE deployment/license would be necessary to run them. It strikes me as insane to require a VS IDE on a build server. We need nant integration please. Then we can plug-in it into our CruiseControl.Net environment without a care in the world.

When you create a project you have the option to select a "profile" which is allows you to chose MSF Agile methodology (the only one available at the moment) which sets up your project with the "standard set of documentation required". I think they missed the point of agile if they think it requires any documentation. Anyway, I guess we can say that they are thinking about the concept anyway. Alex also mentioned that we will be able to set out own standard profiles to help with company standardization.

Alex admitted that the product was pretty shaky but promised performance improvements before its release date. Advertised release dates are in question and Team System will probably be released after the VS 2005 which it is targeted to integrate with.

Conclusion
----------------
Team System allows us to integrate the management of design, source code control, testing and deployment as well as bug tracking and reporting. This is a really good thing for development teams.

The architecture of Team System appears to be completely MS centric which could work for pure MS shops. Alex even mentioned that Team Server only works with the packaged SQL server and they have already received feedback from Oracle shops about having to support another database.

I look forward to trying it out when it is available.

Thanks to Alex for a good presentation.

Additional References
--------------------------------

Microsoft product page

http://lab.msdn.microsoft.com/vs2005/teamsystem/

The .Net Developer Journal story on Team Developer:

http://sys-con.com/story/?storyid=47759&DE=1

If you have a subscription you can see the story on Team Test:

http://sys-con.com/magazine/?issueid=507&src=false