Mark Needham

Thoughts on Software Development

Archive for October, 2008

Test Driven Development By Example: Book Review

with 4 comments

The Book

Test Driven Development by Example by Kent Beck

The Review

I know this book is quite old but I haven’t read it before – it’s been recommended to me several times but I never got round to reading it, possibly because of my somewhat misguided opinion that seeing as I do TDD nearly every day I shouldn’t need to read it.

More by chance than anything else, I was browsing through a friend’s copy of the book and came across several gems of information which persuaded me that I should take the time to read the rest of it.

What did I want to learn?

I have worked in a TDD way for over 2 years now so what I hoped to gain from my reading of this book was more reinforcement – I don’t need to be persuaded by the author that TDD is a very effective approach to software development and I have a reasonable grasp of the basics.

  • What parts of TDD have I forgotten?
  • What patterns are there when TDDing?
  • How closely will the lessons here link to those from Clean Code?
  • What will I learn to allow me to use TDD more effectively?

What did I learn?

  • What stood out for me throughout the examples presented in this book was Kent Beck’s approach to keeping the green bar. Suggestions such as always being one change away from a green bar and implementing code in whatever way makes us reach the green bar faster before refactoring it were new to me. I am often guilty of trying to make too many changes at once so this was a good reminder to take small steps and keep the tests running frequently.
  • Kent described the purpose of TDD as “closing the gap between decision and feedback“. At a high level this is in fact what it’s all about and is something I forget when I’m deeply entrenched in the code. Getting faster feedback is certainly an important thing to aim for when using TDD.
  • One of the things which surprised me about this book was that the pattern being followed to make tests pass involved first of all writing code that was not perfect but which passed the test. Uncle Bob pointed out this same approach in Clean Code – write dirty code than clean it. While I think this approach certainly makes sense in theory, I think in practice it requires great discipline (especially when time pressures are involved) to go back and clean up the code every time. Perhaps there is some balance to be found between making the tests pass and writing a reasonably good solution first time around.
  • Another interesting approach recommended was to write initial tests which are concerned with implementation and then refactor those into ones which test externally visible behaviour. I have certainly been maybe over dogmatic in wanting to only write tests for behaviour of classes, which often makes it difficult to actually get started. This approach could certainly be useful as one to just get something running.
  • The Green Bar Patterns were new to me – these describe ways to get a test to pass. Kent lists three of them:
    • Fake It – Just put any value in to make the test pass
    • Obvious Implementation – Just implement the simple operation
    • Triangulate – Abstract only when there are two or more examples

    I have used the first two approaches before (without knowing they had a name) but have never known when each one is appropriate or whether I’m just being annoying to my pair by using ‘Fake It’. The ideas given around these in the book give me a slightly better idea.

  • Kent keeps a to-do list throughout the examples – he often speaks of avoiding distraction from the current test by simply adding new tests or ideas onto the list and looking at them after the current task is complete. I sometimes find myself going off and trying new ideas before finishing the current one so hopefully using this approach will allow me to remain more focused.
  • Another thing I often wonder with TDD is how big our steps should be – Kent describes TDD as ‘a steering process – a little this way, a little that way. there is no right size‘. To paraphrase – steps of different sizes can be used and we should vary these depending on the situation. If the steps feel too small, make them bigger, and if they feel too big, make them smaller.

In Summary

I think this is certainly a good book for learning how to do TDD – the examples are very easy to follow and the benefit of different facets of the approach are explained with each test & code change.

Even if you have been doing TDD for a while it is still good to get a reminder of the principles behind it and remind yourself of some of the simple tricks that can make the approach even more effective.

Written by Mark Needham

October 7th, 2008 at 11:17 pm

Posted in Books

Tagged with ,

rspec – Invalid character ‘\240′ in expression

with 4 comments

We have been using rspec on my project for the unit testing of our Ruby code and while running one of the specs last week I ended up getting this somewhat en-cryptic error message:

Invalid character '\240' in expression

After convincing myself that this error wasn’t actually possible it turned out that I had somehow entered an ‘invisible to TextMate’ character after one of the method definitions – on the editor it just looked like a space.

I’m not sure exactly what the character was but deleting it got rid of the error and got my test/spec running again.

Written by Mark Needham

October 6th, 2008 at 8:48 pm

Posted in Ruby

Tagged with ,

Calling shell script from ruby script

with one comment

Damana and I previously posted about our experiences with different Ruby LDAP solutions.

Having settled on Ruby-LDAP (although having read Ola and Steven’s comments we will now look at ruby-net-ldap) we then needed to put together the setup, installation and teardown into a ruby script file.

A quick bit of Googling revealed that we could use the Kernel.exec method to do this.

For example, you could put the following in a ruby script file and it would execute and show you the current directory listing:

exec "ls"

The problem with using Kernel.exec, which we became aware of after reading Jay’s post, is that we lose control of the current process – i.e. the script will exit after running ‘exec’ and won’t process any other commands that follow it in the file.

Luckily for us there is another method called Kernel.system which allows us to execute a command in a sub shell, and therefore continue processing other commands that follow it.

We were able to use this method for making calls to the make script to install Ruby-LDAP:

@extconf = "ruby extconf.rb"
system @extconf
system "make"
system "make install"

There is one more option we can use if we need to collect the results called %x[...]. We didn’t need to collect the results so we have gone with ‘Kernel.system’ for the time being.

Jay covers the options in more detail on his post for those that need more information than I have presented.

Written by Mark Needham

October 6th, 2008 at 8:12 pm

Posted in Ruby

Tagged with , ,

Pragmatic Learning and Thinking: Book Review

with 14 comments

The Book

Pragmatic Learning and Thinking by Andy Hunt

The Review

I came across this book when reading a post linking lean to the Dreyfus Model on Dan North’s blog.

I have a keen interest in theories of learning and have completed an NLP Practitioner’s course so the ideas described in the book summary immediately appealed to me.

After coming across the concept of Reading Deliberately in Chapter 6 of the book I decided I should give the SQ3Q approach to reading books its first run out.

I think I did some of the ideas it suggests implicitly but I thought it’d be good to purposely use it. The approach is briefly summarised further down.

I originally intended to buy this book but it wasn’t available before I came to Australia so I got a Beta version from The Pragmatic Programmers website – an idea my colleague recently posted about.

What I wanted to learn

  • Journey from Novice to Expert – How can I use the Dreyfus Model more effectively when learning new skills? Will I learn how to become expert quicker? How can I make use of the Dreyfus model on a day to day basis? Why do some people pick up skills more quickly than others?
  • This Is Your Brain – What things are critical for learning success? How can we best utilise the brain’s design to maximise learning? Is there a difference between how we learn language APIs and design skills?
  • Get In Your Right Mind – What are the L & R modes of the brain?
  • Debug Your Mind – Can you change the way you think? How does the way in which we are taught to think in school limit us?
  • Learn Deliberately – How will the ideas here overlap with Scott Young’s ideas around Holistic Learning? How will NLP theories of learning link to the ideas laid out here? What can I do to master skills more effectively?
  • Gain Experience – How do we keep learning as a key focus in situations where it may not be considered that important? How do we achieve short feedback loops when learning?
  • Manage Focus – Is gathering contextual information around a topic still valuable for learning? I lose focus fairly easily – will I learn how to improve that?
  • Beyond Expertise – What does it mean to be beyond expert in any field?

What I learnt

  • I had heard of the Dreyfus Model before reading this book, but the explanations of it and examples of its application in developing software development skills was especially useful. It has helped me to become more aware of the level I am currently at with skills I use day to day as well as providing pragmatic suggestions on how to improve my level. The ideas around creating continuous improvement by undertaking tasks that are challenging but doable in an environment which provides quick feedback was an idea I have heard of previously but it was good to have it reinforced.
  • Capturing your ideas is one of the early recommendations – I have got in the habit of always carrying around a Moleskine notebook with me since the start of this year. I use it to write down things that I want to learn or read more about at a later stage. When I get the time I go through everything I’ve written down and tick it off. I find this works well because often when pair programming it isn’t productive to go off reading about side topics but equally I don’t want to forget to go and look it up.
  • The idea of the system metaphor for software systems is one which is closely linked to some of the ideas in Domain Driven Design with regards to using clear real life metaphors to represent the way that our system works. I don’t think this is something that has caught on completely just yet but it seems to be covered by such ideas as intention revealing interfaces and by taking an intuitive approach when naming classes and methods.
  • I have long thought that the teaching approach used at universities is completely suboptimal for learning – it is too focused on providing knowledge rather than the ability to solve problems. This is pointed out by the author who does so by questioning the purpose of technology certification programs. He suggests taking a SMART approach to learning – learn something Specific, with Measureable success criteria, make it Achievable, something that is actually Relevant to you or something that you care about, and do all this within a Time box.
  • The author also talks of getting experience in new skills first before learning the theory. I have been trying to take this approach to learning Ruby – we dived straight into the code but often take steps back to ensure that we are using the language properly and not just writing Javaesque Ruby code. When we eventually read about the theory we have a much better context to apply this learning to rather than just reading all the information up front.
  • The SQ3R approach to reading material is something which I have been trying out. To summarise, the approach includes the following steps:
    • Survey – scan the table of contents and chapter summaries
    • Question – note any questions you have
    • Read – read in entirety
    • Recite – Summarise and take notes in your own words
    • Review – Re-read, expand notes, discuss with colleagues

    With this book in particular I found the ‘Survey’ step especially useful – I initially skipped reading 3 of the chapters as they seemed too scientific for me. After reading about this technique I went back to these chapters and became more curious about what I was interested in learning.

  • The idea of linking new information you read about with knowledge you already have using mind maps is something that I first started doing around a year ago. I haven’t done it for a while though and since restarting it a couple of weeks ago I’m noticing more links between things than I did previously and finding learning new information more enjoyable. One interesting point which was made is that it is much more effective when you are drawing the mind map by hand rather than using a software package to draw it. I have never put colours or pictures in my mind maps but this is suggested as another addition to the technique.
  • Test Driven Learning – I really liked the ideas outlined here. One suggestion was that we should try and recall material learnt after 2 minutes, after 2 days, after 2 weeks, after 6 months to ensure we know it well. Other ideas to strengthen the learning process included teaching the concept to a colleague and drawing & re-drawing mind maps. I think writing about something on a blog or similar also helps to clarify understanding.
  • The idea that learning can be fun is one that I found interesting – I have started to come around to this point of view more over the last couple of years having previously only considered learning to be what was done at school. The following quote from the book captures the essence of what is being suggested:

    Working with new material or solving a problem in a playful manner makes it more enjoyable, but it also makes it easier to learn. Don’t be afraid of fun.

  • The author speaks about creating awareness when learning a new skill rather than focusing on what you are doing wrong:

    You want to try to cultivate nonjudgmental awareness: don’t try to
    get it right, but notice when it is wrong. Then act to correct it.

    He also speaks of imagining yourself as being better than you are – i.e. playing the expert. I have read many times that the human mind can’t tell the difference between a real experience and an imagined one so that’s where the logic for this idea comes from. It was actually while reading a book called Mind Games that I first became interested in NLP and then eventually came across this book.

  • In the chapter on managing focus the author speaks of the benefits of meditation – I have never done this as I couldn’t see the benefits of doing so but having read some of the ways that it may be helpful it is something I am going to try out. A type of meditation called Vipassana meditation is detailed.
  • The idea of using TextMate as a Wiki was one which I am now trying out using the Plan Text Wiki TextMate bundle. I currently only keep track of my ideas using MarsEdit, my notepad and Moleskine but this has provided me with a new idea for organising information effectively on my computer
  • The book cites numerous sources for the more scientific information presented. Some of the ones which I have put on my reading list are:

In Summary

I really enjoyed reading this book – there were so many suggestions that really made me think – I’ve tried to cover some of my favourites in my review but there is way more useful information and ideas in this book than what I can do justice to here.

It is a bit scientific in places and I read some of the chapters at the end before some of the more theoretical ones which appear early one. Going back to them afterwards I did realise that there was value in the in this information but that it had worked out better reading the chapters in this order.

Written by Mark Needham

October 6th, 2008 at 2:20 am

Ruby LDAP Options

with 5 comments

As I mentioned in an earlier post a colleague and I spent a few days looking at how to connect to an OpenDS LDAP server using Ruby.

We ended up analysing four different solutions for solving the problem.

Active LDAP

This approach involved using the Active LDAP Ruby which “provides an object oriented interface to LDAP. It maps LDAP entries to Ruby objects with LDAP attribute accessors based on your LDAP server’s schema and each object’s objectClasses”.

We had real problems trying to even connect to our OpenDS server using this library. We eventually found out that OpenDS is not actually listed as one of the supported interfaces.

The real benefit of this approach was that the library is written in Ruby meaning that getting permission to install it would be easier.

The fact that we couldn’t actually get it to work didn’t help!

Java LDAP libraries + RJB

This approach involved interacting with LDAP with Java libraries and then using the Ruby Java Bridge to connect to these from our Ruby code.

We were able to solve the problem quite easily using this approach but the Ruby code we ended up writing was very Javaesque in style and it didn’t feel like we were utilising the power of Ruby by using Java for such a fundamental part of the problem we were attempting to solve.

On the positive side RJB is easily installable via a gem and we were able to connect to OpenDS and execute the operations that were required.


The third option we looked at was Ruby-LDAP, a Ruby extension library written in C.

The disadvantage of this was that we needed to have make available to install it onto our machine. Seeing as we were using a Mac this meant downloading XCode to make use of the GCC compiler.

Interacting with the different libraries was tricky initially but we eventually got the hang of it and were able to connect to OpenDS despite it not being listed as one of the supported libraries.


ruby-net-ldap is a pure Ruby LDAP library, installable via a gem.

This had by far the best examples and most intuitive interface of the options that we analysed and worked for us first time without too much fuss. Connecting to our Open DS server was seamless.


Our original selection, despite the slightly more complicated installation was Ruby-LDAP.

However, Ola Bini pointed out ruby-net-ldap which actually proved to meet our criteria even more closely than Ruby-LDAP did and as such was the option we went with.

For those that are interested, Damana has posted more of the technical details behind the approaches we took.

Written by Mark Needham

October 5th, 2008 at 4:29 pm

Posted in Ruby

Tagged with , ,

Ruby: Ignore header line when parsing CSV file

with 4 comments

As my Ruby journey continues one of the things I wanted to do today was parse a CSV file.

This article proved to be very useful for teaching the basics but it didn’t say how to ignore the header line that the CSV file contained.

The CSV file I was parsing was similar to this:

name, surname, location
Mark, Needham, Sydney
David, Smith, London

I wanted to get the names of people originally to use them in my code. This was the first attempt:

require 'csv'
def parse_csv_file_for_names(path_to_csv)
  names = []  
  csv_contents =
  csv_contents.each do |row|
    names << row[0]
  return names

I then printed out the names to see what was going on:

names = parse_csv_file_for_names( "csv_file.csv" )
names.each do |name|
  puts name

This is what was printed:


It turns out that the ‘shift’ method is what I was looking for to help me ignore the first line of the file. The new and improved method now looks like this:

require 'csv'
def parse_csv_file_for_names(path_to_csv)
  names = []  
  csv_contents =
  csv_contents.each do |row|
    names << row[0]
  return names

Not a particularly complicated thing to do in the end although I had been expecting to find a method on CSV that would allow me to ignore the header line automatically. As far as I could tell there isn’t one!

Written by Mark Needham

October 4th, 2008 at 1:32 am

Posted in Ruby

Tagged with ,

It’s not all about the acceptance tests

with one comment

A few of my colleagues recently posted their opinions about acceptance tests which tied in nicely with a discussion about acceptance testing that was had at the Alt.NET conference in London.

For the sake of argument I will assume that when we refer to acceptance tests we are talking about tests at the GUI level which are being automatically driven by a tool, usually Selenium but maybe something like White if it is a client side application. I’m not sure if this definition is 100% accurate but it feels to me that this is what is being referred to when we describe something as an acceptance test.

The discussion at the Alt.NET conference centered around the value of having these acceptance tests when they often take a long time to run therefore dragging out the time that it takes to build our application. These are some of the same problems that Sarah points out as well as issues around the maintenance of these tests.

Some of the responses to this pointed out that we should not rely too heavily on acceptance tests to confirm the correctness of our system especially when we can often do this using functional or integration tests which do not have to hit the UI and therefore run much more quickly.

We could still have acceptance tests but maybe they would only be necessary for critical scenarios where the system would become unusable if they did not pass – e.g. for the login screen.

I’m not sure what the solution is – I haven’t actually worked on a project which had the problems that Phillip and Sarah have experienced but I’ve heard the horror stories from speaking to some of my colleagues.

Sarah made one particular comment which I can relate to:

In fact, when I finish developing my story, the integration/persistence/unit tests already cover all acceptance criteria.

One of the projects I worked on had the concept of acceptance criteria for every story but we didn’t have acceptance tests so to speak. There were certainly unit tests and functional tests covering each story but that was the extent of our automated testing.

There were a couple of regression issues which we may not have had if we had acceptance tests but overall I felt the approach worked really well for us and the team consistently delivered. At one stage we did try to introduce some White driven GUI level tests but they were never introduced into the continuous integration process while I was on the project.

I appreciate that this is just one scenario and that each project is different but the lessons I took from this was that we should just do what works best in a given situation and not be too dogmatic in our approach.

Phillip actually has a different view and (to probably quote him out of context) believes that having automated acceptance tests is vital:

My main concern is that I think people value Acceptance Testing too much. Don’t get me wrong: automated acceptance tests are essential to a healthy agile process, the problem is what we do with them after we deliver a story.

I do agree that we often place too much emphasis on acceptance testing but I’m not convinced that we need automated acceptance tests to have a ‘healthy agile process’.

As I’ve been writing this the terminology seems a bit strange to me. Is it actually correct to say that an ‘acceptance test’ always implies an automated test that is run from the GUI?

Or can an ‘acceptance test’ be a collection of functional and integration tests which confirm that a piece of business functionality works as expected?

Written by Mark Needham

October 3rd, 2008 at 1:26 am

Posted in Testing

Tagged with ,

Ignore file in Svn

with 2 comments

I spent a bit of time this afternoon marveling at the non intuitiveness of working out how to ignore files in Svn.

Normally I’d just use Tortoise SVN as it makes it so easy for you but I really wanted to know how to do it from the shell!

After a bit of Googling and conversation with a colleague I think I have it figured out to some extent.

Ignoring just one file or pattern

If you only have one pattern or file that you want to ignore then the following command should do the trick.

svn propset svn:ignore <file_or_pattern_to_ignore> <dir_in_which_to_create_ignore_file>

For example:

svn propset svn:ignore build .

This means my ‘build’ directory will now be ignored and the svn ignore file will be placed in the current directory.

Ignoring multiple files or patterns

The problem with the above approach comes when you want to ignore more than one pattern/file. If you just run the propset command again it overrides the current svn ignore file with the current value – clearly not what we want!

Luckily propedit comes to the rescue.

Running the following command will open up your chosen editor and allow you to edit the svn ignore file.

svn propedit svn:ignore <dir_where_ignore_file_resides>

When I initially did this I received the following error:

svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR is set, and no 'editor-cmd' run-time configuration option was found

I wanted my default editor to be Textmate so I entered the following:

export SVN_EDITOR=mate

This didn’t seem to work for me – the svn tmp file being opened up in Textmate was always empty for some reason. Changing my editor to vi seemed to fix the problem.

export SVN_EDITOR=vi

Running the command now opens up vi and allowed me to add the pattern ‘*.log’ to my ignore list. If it is added successfully the following message will show up on exiting vi:

Set new value for property 'svn:ignore' on '.'

Seeing which files or patterns are currently ignored

While having my Textmate problems detailed above my colleague pointed out the propget command which shows you which files/patterns are currently being ignored.

svn propget svn:ignore .

Running this command shows me the following:


svnbook has even more goodness on ignoring files for those that are interested.

Written by Mark Needham

October 2nd, 2008 at 9:10 pm

Posted in Version Control

Tagged with ,

Ruby: Unzipping a file using rubyzip

with 9 comments

In the world of Ruby I’ve been working on a script which needs to unzip a file and then run an installer which is only available after unpacking it.

We’ve been using the rubyzip gem to do so but so far it hasn’t felt intuitive to me coming from the Java/C# world.

ZipFile is the class we need to use and at first glance I had thought that it would be possible to just pass the zip file name to the ‘extract’ method and have it do all the work for me!

Turns out you actually need to open the zip file and then create the directory location for each file in the zip before extracting them all individually.

We eventually ended up with this little method:

require 'rubygems'
require 'zip/zip'
def unzip_file (file, destination) { |zip_file|
   zip_file.each { |f|
     zip_file.extract(f, f_path) unless File.exist?(f_path)

Which we can then call with the zip file and the destination where we want to unzip the file.

unzip_file("", "marks_zip")

Is there a better way to do this? It feels a bit clunky to me at the moment.

Written by Mark Needham

October 2nd, 2008 at 12:04 am

Posted in Ruby

Tagged with ,

Alt.NET Sydney User Group Meeting #1

with 3 comments

James Crisp and Richard Banks arranged the first Alt.NET Sydney User Group meeting held on Tuesday night at the ThoughtWorks office.

The first thing to say is thanks to James and Richard for getting this setup so quickly – it was less than a month ago that Richard suggested the idea of creating a group on the Alt.NET mailing list.

Richard and James have already written summaries of what went on but I thought I’d give some of my thoughts as well.

The meeting was split into three parts with a retrospective on proceedings at the end:

.NET News

Richard opened the meeting by talking about some of the latest news in the .NET community in the last month or so.

I thought this worked very well and helped to get some discussion going very early on. One of my comments from the London Alt.NET Conference was that very few people seemed to get involved – that certainly wasn’t the case last night and there was a very collaborative feel about the whole event.

The first news was that the much talked about jQuery is going to ship with ASP.NET MVC and Visual Studio and that Microsoft intend to provide Product Support Services for it and contribute any changes they make to it back into the community. It was suggested that this is a bit strange as jQuery is effectively a competitor to Silverlight – Microsoft’s plugin for developing rich applications for the web. Apparently Nokia are also intending to get involved.

Another thing which I hadn’t heard about was the DevSta coding competition which was mentioned at Tech Ed earlier in the year. I haven’t read exactly what the competition is all about but you get 200 hours and 8 minutes to prove your skills with Visual Studio 2008. The challenge is here for those that are interested.

Richard also pointed out some open source projects which I hadn’t come across, notably CloneDetectiveVS – a duplicate code finder plugin for Visual Studio – and SnippetDesigner – another plugin to create code snippets. Not sure how different this would be to Resharper’s code templates but it’s another option.

A new language which runs on the CLR called Cobra was mentioned. It has support for contracts and testing so it could be a contender – probably needs someone high profile to run with it for that to happen I would imagine.

gocosmos was also discussed – an operating system project implemented completely in CIL compliant languages.

The WebDirections conference was also mentioned – the Microsoft Surface seemed to be the most interesting thing to come out of this.

Ruby and Rails From a .NET Perspective

James opened the second half of the evening with a talk about using Ruby in the world of .NET.

He opened with a brief history of the Ruby language going through some of the ideas that Ruby brings to the table – principle of least surprise being the most intriguing one to me – before covering some of the Ruby compilers currently available – MRI, YARV JRuby and IronRuby. The last one was the focus for the talk – being a .NET implementation of the Ruby language.

James went through some demos using the Interactive IronRuby Console to start with but later showing how to create a simple application using Rails.

There was an interesting discussion around testing – James pointed out that the Ruby/Rails world is much more test focused than the .NET one and unit testing is available right out the box.

I haven’t worked with Ruby enough to know if everyone in the Ruby world unit tests but as a general feeling I would say this is probably accurate.

RSpec was covered briefly as an alternative to the Test::Unit framework that comes baked in with Rails. I haven’t played around with it before but as I’m working a bit in the world of Ruby at the moment it is something that I hope to use in the near future.

Finally build and deployment tools from the Ruby world such as Capistrano and Rake were mentioned. I can see the latter having some influence but as the former is meant for Unix I can’t see it being heavily used in the .NET world.

Rhino Mocks

Richard closed the evening with a presentation on Rhino Mocks.

I went into this presentation with the belief that Moq was the way to go when it comes to .NET mocking frameworks.

The Arrange Act Assert or Mockito approach to mocking is one which makes it much easier to do and leads to far less clutter in tests.

I thought this was only possible in Moq and that Rhino Mocks encourage the Record/Replay approach. As Richard pointed out, this is no longer the case.

Richard gave a demonstration on several of the ways that you can use Rhino Mocks in your testing efforts – covering simple interaction testing, event testing and several other clever techniques that Rhino Mocks allows.

An interesting statement was made that ‘Mocking = Genuine Unit Testing’, a statement that I tend to agree with. Several people mentioned that they now realised their unit tests were actually functional tests – this is a problem which mocking can help to reduce.


Overall it was again interesting to meet up with the .NET crowd and hear the different ways that people are doing – I was impressed with the turn out given the short notice – there were over 30 people in attendance.

The next meeting is on 28th October 2008, ThoughtWorks Sydney Office, 51 Pitt Street again.

Written by Mark Needham

October 1st, 2008 at 10:09 pm

Posted in .NET

Tagged with , , , ,