Tuesday, December 09, 2008

Telling a good Story with RSpec

RSpec recently dropped their StoryRunner in favor of Cucumber.

Dispite that, Joseph Wilk's post on "what makes a good story" is still a great place to get started, if you're looking for some pointers.

Works for me :)

Friday, December 05, 2008

Great Hackers

I heard a good talk by Paul Graham on what makes a Great Hacker.

The bit that stuck with me was the idea of getting your great hackers to write the tools or building blocks that let the others write the apps.

I love that idea.. I think I keep gravitating that way.

Monday, November 17, 2008

Getting Cyclometric Complexity in PHP

I have some legacy code I am analyzing at the moment. I needed a tool to report Cyclomatic complexity for PHP code.

I found Lint PHP which is a web form in which you can post your code to be evaluated. Now I'm not going to post all my code to some 3rd parties page. Luckily you can download the code.

After installing PHP ...

I used [ XAMPP. Just unzip it made that painless] I put the code in the htdocs directory and visit http://localhost/lint_php.php and there you go .. a local copy is running.

Next problem... I have around 200 pages all spread through a directory structure I want to submit to this form..

This is where Ruby and Mechanize come in.

I found a bug with Mechanize at this point that slowed me down.. :(
You are supposed to be able pass blocks to forms, like so...

... but that didn't work for me.

I finally got the following working..


So.. now I can call

phpcc C:\Projects\PHPStuff\src

and get out some figures.

All this reports is the worst methods complexity and a total for the code submitted.
How useful this is I won't get into, but you can change it to report whatever you like from the list generated in the code.

Hope this helps :)

Tuesday, November 11, 2008

Matching Ruby Regular Expressions Across Lines

Just a quick note: x.matches(/something.*/) will match all of one line.
To match all lines x.matches(/something.*/m) you need to put the 'm'.

Nice!

I found it here.

Wednesday, October 29, 2008

Transform a Twiki Table

I needed to change a TWiki table to make the rows become columns and columns become rows.

Ruby + 5 mins =

table = <<-TABLE
...paste table here...
TABLE

rows = (table.split "\n").collect { |line| line.split("|") }
puts (0.. rows[1].length).each { |col| puts "|#{rows.collect{ |row| row[col] }.join("|")}|" }

Ahhhh.. That could have been painful.

I love being a programmer. How do people that don't code handle this sort of problem?

Document-oriented Data Storage

There seems to be new interest in the concept of storing data as documents instead of tables. This is the approach that Lotus Notes took. Here is what I ahave found out so far...

A 'document' is basically a hashtable. You can store values with keys. Solutions then seem to take the Google "Map Reduce" approach to querying the data.

CouchDB allows you to define views. A view contains the results of executing a specified javascript function against each document. This is equivolent to the Google 'Map' step.

RDDB (a ruby implementation) provides for both steps...
  # First create an database object
database = Rddb::Database.new

# Put some documents into it
database << {:name => 'John', :income => 35000}
database << {:name => 'Bob', :income => 40000}
database << {:name => 'Jim', :income => 37000}

# Create a view that will return the names
database.create_view('names') do |document, args|
document.name
end

# The result of querying will return an array of names
assert_equal ['John','Bob','Jim'], database.query('names')


"Map Reduce" scales really well across machines, so I am keen to see where this goes.

I'll let you know what I find out.

Anyone got any pointers?

Tuesday, October 28, 2008

Dos Prompt for Long Paths

If you have to work with DOS at some point you find the display muddled due to deep directory trees cluttering your display.

A simple solution is setting the environment variable PROMPT=$p$_$+$g

This just adds a newline to the end of the prompt.. but makes all the difference.

Thanks to Florin Lazar for this tip

Using Outlook like Gmail 2

I forgot to mention...
Install GoogleDesktop to get much better searching through your emails.

Tuesday, October 07, 2008

Using Outlook like Gmail

I love GMail's 'Archive' feature. I wanted the same in Outlook which I am currently forced to use. So...

Sub Archive()
Dim myItem
For Each myItem In Application.Explorers.Item(0).Selection
myItem.UnRead = False
myItem.Move (Application.Explorers.Item(1).CurrentFolder().Parent.Folders("Archive"))
Next
End Sub


This little macro marks the current selected item(s) read and moves them to the 'Archive' folder (that you will need to create at the top level).

I also added a button to run the macro and called it "&XArchive" so I can go Alt+X to archive the currently selected mail item.

Works for me..
If anyone can be bothered to get it to work for all selected items that would be cool. Done...

Oh, I'm using Outlook 2000. You may need to change the macro for other version.
Let me know :)

Wednesday, October 01, 2008

Don't Drop the Bar!

You're hiring... you make a list of mandatory skills and some preferred ones. You interview someone... they don't get ticks in all the mandatory fields... so easy decision. They are mandatory! You have to say no.

Now... some time passes... you are interviewing people, but no-one seems to be passing the bar. Time is running out. You have to staff your project or it won't be viable. What do you do?

What would you do?

My thought for the day..

Staffing a project with the wrong people WILL LEAD TO FAILURE! Usually a slow, expensive failure. Having the project canceled because it wasn't viable is a much better business decision, and in the long run may save the company (and your job).

Sunday, September 14, 2008

A Nice Summary of Ruby MetaProgramming

Check out this simple introduction to metaprogramming. I have an article bubbling away in my head about why in .Net I need tools like NDependencyInjection, but in ruby you don't.

You really do need tools like NDependencyInjection in .Net by the way.. I'll explain that too.

MapReduce in Ruby

Some guys at Google came up with this idea of specifying a set of problems as two stages processes.

Step 1: Map (come up with a mapping function that takes a key value pair and maps it to a new set of key value pairs)
** do this for all key value pairs **
Step 2: Reduce (for each of the new key values, take all values and reduce them down to a single value)

Any problem that can be broken down into these steps can be parallelized really easily and scales well by adding more boxes.

An example may be 'Count word occurrence on the web'
Mapping: [word, url] => for each occurrence of 'word' in document@url add an item to an output hash for value 'word'
Reduce : [word, values] => number of items in value list 'values'

Anyway... lots of problems can be defined in this way... the code that runs your map/reduce functions for you can solve all sorts of problem handling networking issues, machine loading, etc...

Blaine Cook wrote a version in ruby here. Or see mapreducerb@github

I can't wait to have a play with this.

Saturday, September 13, 2008

Maximize window in osx

Finally someone has got some scripts together to maximise windows in osx.

OSX has this weird idea that you want to see lots of windows at once. "Maximizing" a window therefore means make it big enough to show the content of the window, but not too big. This leaves the application to decide how big is big enough. Some apps do this fine... others (like Preview) keep getting it wrong.

Grab these scripts form git hub. From a terminal type "rake install", then type "rake install_fastscripts" so you can map the scripts to keys easily. Once you have this working map Maximise to something like Ctrl + Apple + M and you can now make one app take over the whole screen.

THANK YOU TopFunky THANK YOU!

A couple of the scripts are hardcoded to use Terminal, so I have forked the repository for my own edification. I also want to fix a problem with the scripts expecting the draws to be on the right hand side of a window.. which it isn't always.

Lisp in Ruby... amazing

http://onestepback.org/index.cgi/Tech/Ruby/LispInRuby.red

You have to check this out if you have any interest in programming languages at all.

Wednesday, August 27, 2008

Make a Bootable USB from a DMG

Here's the simplest process I have seen...


  • Mount a bootable DMG image so it appears in /Volumes (eg. /Volumes/SomeAppDisk)

  • Mount a USB Key you don't mind erasing (eg. /Volumes/USBToBeWiped ) (should happen just by sticking it in the machine)

  • From a terminal type
    sudo asr --restore --source /Volumes/SomeAppDisk --target /Volumes/USBToBeWiped --erase

  • wait ....10....20....30....40....50....60....70....80....90....100


Note: --erase will cause the usb key to be wiped AND is what 'bless'es the device so it becomes bootable.

There you go..

Running a .NET Executable from a Network Drive

Rob Smyth is developing NUnitGridRunner, a tool to run nunit.console on several machines at once.

As any application under test grows, so does the number of UATs. Rob's project aims to allow us to scale the running of UATs by adding network boxes.

What does this have to do with Running .NET executables on network drives?

Well, Rob needs to distribute the latest version of the assemblies and tests to each machine so they could run the tests. It's simpler if they just all run from a network path. ,However .NET got in the way.

1/2 a day later we had a solution.

If you run nunit-console.exe from a command shell accessing it from the network drive, you get the following error.


Unhandled Exception: System.Security.SecurityException: That assembly does not allow partially trusted callers.
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, Runti
ityAction action, Object demand, IPermission permThatFailed)
at NUnit.ConsoleRunner.Class1.Main(String[] args)
The action that failed was:
LinkDemand
The assembly or AppDomain that failed was:
nunit-console, Version=2.4.6.0, Culture=neutral, PublicKeyToken=null
The method that caused the failure was:
Int32 Main(System.String[])
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://aumelw021202/GridRunnerSandPit/AUMELW061120/nunit-console.exe


This is due to .NET's permissions system. There are lots of articles online telling you how to recompile your exe to make it run. This is a 3rd party exe though, so I don't want to have to recompile it. That would mean that each time I want to upgrade I would have to do extra steps.

Anyway.. here is the solution I used.

First I changed the Zone that .Net things the network drive belongs to.


Control Panel >> Internet Options >> Security >> Local Intranet >> Click Sites... >> Advanced...
in 'Add this Web site to the zone:' enter the network path.. and click Add
eg. \\MyNetworkMachine\DirectoryContainingExe

You can test this worked by running the executable again from a dos prompt...

The Zone of the assembly that failed was:
Intranet


Notice it moved to Intranet.

Now all you have to do is tell .NET to trust executables in that zone.


Control Panel >> Administrative Tools >> .NET Framework 2.0 Configuration >> Configure Code Access Security Policy >> Adjust Zone Security >> Next >>

Click "Local Intranet" and slide the slider up to Full. Then click Next a couple to of times.

You can now run the executable... TADA!

What you've done is allow .NET assemblies in the local intranet to be executable on your machines. If this represents a security risk for your machines then this is not the right solution for you.

For us it works great.

Sunday, August 24, 2008

Design Patterns in Ruby

Neal Ford gave a great talk at erubycon about the use of Design Patterns in ruby.

I really liked a couple of tips on how to use interfaces as named groups of methods and mixin's for states.

Tuesday, July 29, 2008

ActiveRecord SQLite3 "unable to open database file"

I am starting up a Hobo based project that will appear sometime soon. I made a simple mistake, so I thought I should share.

I ran something like this... sudo hobo code_blog
I got a few missing gem problems, so I did a few sudo gem install X.
I did a few ./script/generate hobo_model_resource X.
Finally I get to ./script/generate hobo_migration
and ./script/server

With excitement I fire up firefox and get a lovely screen. I attempt to sign up and get

ActiveRecord::StatementInvalid: SQLite3::SQLException: unable to open database file: INSERT INTO users ("salt", "updated_at", "crypted_password", "remember_token_expires_at", "username", "administrator", "remember_token", "created_at") VALUES('xxxxxxxxxxxxxxxxba4739cda76', '2008-07-28 22:16:31', 'xxxxxxxxxxxxxxxxxxx99537dd568', NULL, 'nigel', 't', NULL, '2008-07-28 22:16:31')
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract_adapter.rb:150:in `log'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/sqlite_adapter.rb:132:in `execute'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/sqlite_adapter.rb:345:in `catch_schema_changes'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/sqlite_adapter.rb:132:in `execute'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:156:in `insert_sql'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/sqlite_adapter.rb:146:in `insert_sql'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:44:in `insert_without_query_dirty'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:19:in `insert'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2272:in `create_without_callbacks'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:226:in `create_without_timestamps'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/timestamp.rb:29:in `create'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2238:in `create_or_update_without_callbacks'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:213:in `create_or_update'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1972:in `save_without_validation'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb:934:in `save_without_transactions'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:66:in `transaction'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:80:in `transaction'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:100:in `transaction'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:120:in `rollback_active_record_state!'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'
from (irb):7>> exit


OK, so do you spot the mistake?

Well it's the sudo in sudo hobo code_blog.

This made the hobo files all owned by sudo.

The fix.. sudo chown nigelthorne code_blog/* obviously with your username and project directory.

We live a learn. :)

Monday, July 28, 2008

Removing Redundant code with NDepend

As we refactor our code, some design changes make some existing code redundant. When you have unit tests on all your code you can't find this using coverage. So finding this redundant code can be tricky.

What you need is a tool that can analyze your code base. The best I have found for .Net is NDepend.

NDepend provides a query language for code.

I started a project and added all assemblies except the test ones. I then ran the query :
SELECT TYPES WHERE TypeCa == 0

TypeCa refers to the 'Afferent Coupling' of the type.. ie. how many other types refer to this one.

This found 40 files I could delete.

I used Resharper to double check each one was not used (except in tests).

I got a couple of false positives with types I am only using to pass as type parameters to generic classes. This is the only thing stopping me adding this check as part of our build script.

Finding all those classes by hand would have taken much longer, so...

Works for us!

Thursday, June 19, 2008

We switched from NCover to NCover 2.0

NCover is an invaluable part of our continuous integration server. (In conjunction with NCoverCop [shameless plug]).

We recently splashed out on the commercial version [NCover 2.0] rather than use the open source version with an aim to speed up the build.

The upgrade was pretty painless. I needed to extend NCoverCop to process the new file format, so the next version will now handle both. It can even compare one against the other.

The results




We managed to shave 2 minutes off the build. Every little helps!

Tuesday, June 17, 2008

Mocking Generic Method with NMock2 (part2)

Well although this feature has been mentioned on the web it doesn't seen to exist in any version of NMock2 I can find. With a bit of digging I worked out how to implement it myself.

You can download the assembly from NMock2Extensions try it out, or download the source from svn.

Here's an example of using it...


Stub.On(childScope)
.Method(new GenericMethodMatcher("Get", typeof(IControl)))
.Will(Return.Value(control));

Expect.Once.On(childScope)
.Method(new GenericMethodMatcher("Get",typeof(IDocument)))
.Will(Return.Value(NewMock()));


As you can see, you can Stub or Mock on the same method with different generic types and they are handled differently, as you would expect.

Happy Mocking

Wednesday, June 11, 2008

Getting Started with NDI

Check out Getting Started with NDependencyInjection. I'm looking for some feedback. How readable/followable is it?

Sunday, June 01, 2008

Mocking templated methods with NMock2

Mocking a method like T GetSomething();

This is something that I have resorted to RinoMock to achieve in the past...
... well it turns out you can do it with NMock2 v1.0 as follows:

Expect.Once.On(a).Method("GetSomething", typeof(int)).Will(Return.Value(42));

I've tried to find this before.. and failed.. so I thought I should blog it to make it easier to find in google.

Thanks to ursenzler for commenting on http://www.fluidscape.co.nz/?q=node/82#comment-1692

Saturday, May 03, 2008

NDI: Unexpected bonus

NDependencyInjection Update:

Now that most of the code-base is using NDI we are really seeing the benefits.

The main bonus I'm getting is with how simple refactoring has become. Once you have the architecture modeling reality, whenever a class needs a service the correct instance is already available in the scope. This means all you need to do is ask for it in the constructor and it all just works. No wiring changes.

Wednesday, April 16, 2008

When did you last do a "Chicken Run"

"Chicken Run": The process of checking in new code and then leaving before the build has completed, leaving others to deal with the build if it breaks.

Monday, March 17, 2008

Quick svn trick

Here's a one liner to update svn with your local changes.


svn st |awk '/\?/{print "svn add " $2};/\!/{print "svn del " $2}' | sh


Sure there are problems with it... like if the filename has ? or ! in it, then it'll do the wrong thing, but it works for me, so I thought I'd share :)

Thursday, March 06, 2008

NDependency Injection: HasCollection Enforces Layered Architecture

I recently added a feature to NDependencyInjection called "HasCollection".

It lets you specify a set of subsystems that all provide the same interface and so can be viewed as a collection.

ISystemDefinition book = new SystemWiring();

book.HasCollection(Page1, Page2, Page2).Provides();


Here Page1, Page2, Page3 are all of type ISubsystemBuilder, which each define the wiring of a specific IPage.

You can only expose something from one of these subsystems if all subsystems implement it. This has the side-effect of enforcing Liskov's Substitution Principle.

At first this feels limiting, but it is leading us to better designs.

Tuesday, February 26, 2008

Dependency Injection

I have released an early version of a Dependency injection framework I am developing. Yes another one!

NDependencyInjection is being used in a real application and is under heavy development. I intend it to be very opinionated. It will make writing apps the way I write them easy.

First decision: Only support constructor injection.


This decision is not without it's complications. Not least of which is 'what do you do about objects that refer to each-other?'. Luckly I have a solution to this problem. The injection framework in-fact automatically solves these loops.

Second decision: Applications should be built in layers.


When assembling the complex network of simple objects that make up a good design. You group them into sub-assemblies and these into bigger assemblies until you have your final application.

Within the Application there are objects that you only have one instance of. These are by definition Singletons.

Within the sub-assemblies you get classes that act as Singletons, but only within that scope. You may have several instances in your application, but the individual sub-system only has one, and all references to that type refer to the same instance. In all respects this is a ScopedSingleton.

The framework supports Scopes and Singletons.
More on this later.

Anyway.. for now.. you can get at an early release version from NDependencyInjection.

Prefactoring

I have found it valuable to distinguish between the refactoring done in Red-Green-Refactor and the Refactoring done when I have a new story to implement and the design needs to change to accommodate the new feature.

This second form I call Prefactoring.

Prefactoring is performed on otherwise clean well factored code in preparation of a new feature. Prefactoring is perfectly normal on any XP project and in-fact indicates a healthy ongoing design process.

The distinction grew in my mind when we were facing a lot of exiting code debt. I needed a way to distinguish between the 'repair work' I was doing and the 'perfectly acceptable design work'. This was in response to questions like "How much more refactoring is left?" which really meant "How much repair work is left?".

A quick word on Prefactoring and Iterative Design.

Ideally your design applies the OpenClosedPrinciple, which would imply that adding new features would simply require you to add new code. That is great as long as the feature fits one of the axis you have opened your design to change.

However YAGNI indicates you should keep your code as simple as possible. Attempting to open your design to changes in more ways than you currently need can be over-design.

The solution is that you keep your code simple but Prefactor when you need your design to be open in a new dimension. You can then simply add the new feature by adding code. Utopia!

Splitting the work into these two steps makes implementing new features a much simpler process. The new tests are always easy to write. The design always nicely accommodates the the new feature.

As ever, I appreciate Rob for shaming me into finally blogging about this and helping me separate the dumb ideas from the gems.

Thursday, January 24, 2008

Dynamic .Net

Thanks to LinFu C# has DuckTyping, MixIns, MultiDispatch and much more...

I'm already used this library for a new open source project, I'll blog on that next.

GitHub Projects