# Wednesday, August 19, 2009

I’m really liking Ruby on Rails for numerous reasons, and chief among these reasons is the ability to make a change to Ruby code and then refresh the browser to see the changes.  In other words I really like to avoid paying taxes, and in this case the compilation tax we all pay when using a static language.

For a couple of years now, since I started using MonoRail back in 2007 I’ve always felt that productivity could be improved by writing not only views in a dynamic language, but the controllers too (maybe the entire app). There’s just something refreshing about making a change in server side code and immediately see the changes without waiting 30 seconds for a complete recompile of the entire application.

Yesterday I was heavily doing some TDD on a very low level componenent in our application and wasted about 10 minutes waiting for Visual Studio to recompile the project I was working on… and then every other project that depends on that one. It takes a lot of focus to keep the TDD rhythm going when you’re forced to wait 1 minute between runs.  I just have one word for this, painful.

I can only imagine the benefits of doing TDD with a dynamic language since you have a whole lot more compile and test cycles with TDD than traditional programming techniques. The emergence of TDD over the past few years along with general acceptance of the practice will only further push teams towards dynamic languages. Sure you lose static type safety, but that’s why we have lots of good unit tests; and at the controller level that’s not a bad thing because you’re often dealing with key value pairs (think web form post or json DTOs) and a dynamic language is just a much more natural fit.

I’m not completely sold that unit testing at the controller level always makes sense, it often involves too many collaborators and whole lot of mocking. With automocking this isn’t so bad, but sometimes you have complex Ajax interactions in the middle and testing at a higher level via a web test sometimes makes more sense.

I’m hoping Microsoft seriously starts supporting dynamic languages (the DLR) and makes it a first class citizen rather than pushing it to the side in favor of more C# language sugar. I was very disappointed to see that Visual Studio 2010 has no support what so ever for Python or Ruby (unless I completely missed it somehow). Actually, I was shocked! The future belongs to dynamic languages and Microsoft is almost completely ignoring them. If they would support them officially along with ASP.NET MVC, the .NET world would be a whole lot better off.  Without dynamic languages the ASP.NET MVC 2 gets a B in my grade book (version 1 gets a C). Maybe its time to switch platforms?

.NET | IronPython | MonoRail | RoR
Wednesday, August 19, 2009 3:47:59 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, June 26, 2009

I've been using IronPython as of late, not a whole lot, but more and more - and I want to do things the Pythonic way using the built in Python libraries whenever possible rather than .NET BCLs.  I've been using REPL mostly, but I'm starting to do more and more in Python, so I've started using SharpDevelop mainly because it supports IronPython out of the box and is a much smaller download than IronPython Studio.

The problem I had was getting access to the standard Python libraries from SharpDevelop, it appears that SharpDevelop only ships with the IP interpreter and not the Python libraries.  The regular IP install does ship with all the libraries, so how can we get SharpDevelop to use them?  Also, how do we get SharpDevelop to use the latest version of IP that I have installed on my system?

Start an IP project in SharpDevelop.  Remove all references to IronPython from the project (assembly ref).  Add a new reference browsing to your latest installed version, mine is in C:\Program Files\IronPython 2.0.1.  Add a reference to IronPython and IronPython.Modules. In SharpDevelop go to Tools | Options | Tools | Python, and browse to ipy.exe in your IP install directory.

Now that we have a working SharpDevelop IP environment running the latest version, lets go ahead and use some Python libs!  Notice how I explicitly set the Python libs path.

import sys
sys.path.append(r'C:\Program Files\IronPython 2.0.1\Lib')

import os.path

def walkDir(arg, dirname, names):
	print dirname

os.path.walk(r'C:\', walkDir, '')
Thursday, June 25, 2009 11:57:17 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, December 22, 2008

I've been playing around with Grails on my Ubuntu box for the past week and really like the ability to do fast web development while still retaining all the power that the JVM provides.  Unfortunately, it also comes with the baggage of Java, which became pretty apparent once I needed to map a date time object.

Since I still have a day job, and I don't see us switching from .NET anytime soon, I thought I would spend a little time with ASP.NET MVC and IronPython to see where things are. I was able to find a sample MVC sample application on CodePlex which made use of IronPython in the views and the global.asax. The one feature I really wanted support for was writing controllers in python, apparently that's in the works but not currently supported.  Not much python in the sample, but pretty neat to know it works.

... Well actually at some point it probably did.  I'm using the first beta release of ASP.NET and some things have changed since the IronPython sample came out.  Needless to say, the sample no longer works, I get an HttpParseException with the message "HtmlHelper' object has no attribute 'ActionLink'"

Pretty strange message huh?  In C# I can find this method no problem. Long story short, IronPython can't use extension methods like C# can.

At some point the MVC team moved the HtmlHelper.ActionLink method from System.Web.Mvc to Microsoft.Web.Mvc.  The latter is the ASP.NET futures assembly, which provides a bunch of extension methods that they may add to the System DLL at a later date.

Monday, December 22, 2008 7:34:35 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 11, 2008

The other day I asked a coworker whether one our proprietary GUI based tools had a command line interface, to which he replied no.  I said that's cool, we don't really need one to run the tool headless from the command line anyway.  Command lines are antiquated.

Before the days of Windows command shells were the only way to run applications.  Command lines allow us to pipe input and output, batch programs, and otherwise automate repetitive tasks.  In *nix-land they are especially sharp tools.  However they are not without their own problems, foremost in my mind is argument processing.  Using a command line version of an application can be a pain, especially for any non-trivial app. 

If you look at any serious application that allows automation, they have their own automation framework.  Office allows you to write VBA, .NET, and also exposes a COM automation interface.  Maya has its own scripting language (Mel script, guess what Mel stand for) embedded in it along with the ability to run C++ plugins.  Now I bet you're thinking, yes big applications use automation frameworks and scripting languages, but I don't have that kind of time to invest in my little app.  Good, me neither.

In recent years Microsoft has provided less heavy handed approaches to consuming .NET assemblies. There are a couple different approaches that I can think of to use our .NET objects from the command line without writing a console application: Windows PowerShell and the DLR. 

PowerShell is more geared towads sysadmins, as such I like to use the DLR, more specifically IronPython.  Python is a very easy language to pickup, widespread (at least in the *nix world), and powerful.  I like to think of IronPython as C# without all the typing (OK, I stole that from Boo, but remember Boo syntax is based on Python).  Both have one important ability which we will need, the ability to use .NET assemblies and types from the command line (or script).

As an example I have a .NET library assembly that will run JSUnit tests, however I now need a way to run these unattended from the command line as part of a BVT.  Instead of writing a command line app for it I decide to write a quick little IronPython script which behaves very much like a console application.

import clr
import sys

clr.AddReferenceToFile("Sneal.JsUnitUtils.dll")
from Sneal.JsUnitUtils import *
from Sneal.JsUnitUtils.Browsers import *
from System.Collections.Generic import List
from System.IO import Path

# usage
if sys.argv.Count < 3:
	print "Usage: ipy IPJsUnit.py c:\source\mywebroot jsunittest1.html jsunittest2.html"
	sys.exit(False)

# command line params
webRootDirectory = sys.argv[1]

testFiles = List[str]()
for arg in sys.argv[2:]:
	testFiles.Add(Path.Combine(webRootDirectory, arg))

# create an execute test runner
mgr = JsUnitTestRunnerFactory()
runner = mgr.CreateRunner(testFiles, webRootDirectory, With.InternetExplorer)
success = runner.RunAllTests()

# print all results
if not success:
	print "Test run failed."
	for error in runner.Errors:
		print error.TestPage
		print error.FunctionName
		print error.Timing
		print error.Message
else:
	print "Yay!  All tests passed."

You'll notice that the application in fact takes two+ command line parameters, the webroot and the test files.  The advantage of this script over a console application from my point of view is:

  1. Less code to write.
  2. Documentation by example.
  3. Starting script for an end user to modify to their needs.

Number 3 I think is particularly important.  Within a minute or two an end user can modify this script to their needs and desires.  They could hardcode the arguments if they wanted, or pass additional arguments without the headache of launching Visual Studio and recompiling a console application.  Almost anyone with a text editor could modify this and quickly get on with their life.

Here instead of a well meaning (but over-complicated) console application, its been replaced with just enough glue to bootstrap us into business.  Gluing components together is what scripting languages are good at, so lets take them into consideration instead of always reaching for another console app.

Tuesday, November 11, 2008 2:20:47 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  | 
# Sunday, November 02, 2008

Generating test data for your application is not an uncommon task, but there are definitely many different ways to seed your application.  Probably one of the most common ways is to use SQL scripts to directly import data into the database, although while fast this lacks the control and validation that your middle tier code provides.

Loading data directly using SQL works best when your business logic resides in stored procedures near the database, but in a modern application where business logic is generally found in the middle tier application layer written in C#, this doesn't work quite as well.  Loading data directly could potentially cause data corruption since its perfectly plausible your data may very well be invalid.  Besides of the possible side effects of invalid data you're likely skipping some of the automatic management of data your middle tier affords you.  In other words, loading data using your middle tier API is probably more robust and easer to script.

To script the middle tier API to load data we could create data using C# or some other static language, but unfortunately that requires a compile and is much more rigid than a malleable SQL script.  Making the C# "script" data driven does help, but it lacks the flexibility that a native scripting language provides.

With a scripting a language the only part to manage is the script itself which gets checked into source control (or even a My Documents folder).  The other nice benefit is that we can have a nice GUI tool (test suite manager?) that dynamically picks up user scripts from one or more predefined script folders making them a available to run at the click of a button.  No recompile, or reloading, just edit-save-and-go.

So, given that we have a C# middle tier layer that's perfectly capable of persisting data into a database, how do we go about writing a script against it?  There are a few ways, but one of the easiest ways is to use IronPython.  If you're not familiar with IronPython:

IronPython is a new implementation of the Python programming language running on .NET. It supports an interactive console with fully dynamic compilation. It is well integrated with the rest of the .NET Framework and makes all .NET libraries easily available to Python programmers, while maintaining full compatibility with the Python language.

That's exactly what we need!  Something light weight and easy to mange like SQL, but interacts with our middle tier.  We could even embed the interpreter in our GUI runner if we so desired which gives us the full power of a real scripting language and .NET from our own tools.

I created a small spike that tests out how IronPython could be used to load data directly through the middle tier API.  First of all I created a Customer domain object, an Address component, and a CustomerRepository in C#.  From here we directly write Python against this.  Here's what my little spike project looked like:

image

For my purposes I've created a Scripts folder to hold my Python scripts (in a real environment these would probably be located elsewhere).  As you might have inferred, the 10Customers.py script creates 10 customers in my customer repository.  I could potentially add other scripts in this folder, and even chain them together to do other more substantial things, but for now this will do.  Now for the interesting part, the python script which loads ten semi-random customers.

import sys
import clr

sys.path.append(r"E:\Source\spikes\IronPythonSpike\IronPythonSpike\bin\debug")
clr.AddReferenceToFile("IronPythonSpike.dll")
from IronPythonSpike import *
import System.Random as Rand

rand = Rand()
names = ["Joe", "Bob", "John", "Smith", "Hank", "Aaron", "Neal", "Pat", "Tim", "Jones", "Bill"]
streets = ["128th St. W", "Main St.", "1st Ave.", "A.B.D. Rd.", "Lonely Lane", "Pacific Ave.", "6th Ave.", "Foobar Ct."]
states = ["WA", "OR", "CA", "NY", "AK", "NV", "AL", "TX", "FL"]

repository = InMemoryCustomerRepository()
	
for i in xrange(10):
	c = Customer()
	c.Id = i;
	c.FirstName = names[rand.Next(names.Count)]
	c.LastName = names[rand.Next(names.Count)]
	c.Address = Address()
	c.Address.Id = i
	c.Address.HouseNumber = rand.Next(32767);
	c.Address.Street = streets[rand.Next(streets.Count)]
	c.Address.State = states[rand.Next(states.Count)]
	c.Address.PostalCode = rand.Next(10000, 99999).ToString()
	
	repository.SaveOrUpdate(c)

The first thing we do is import sys which we use to add the path to our C# DLL to the available path's for the interpreter to search for our DLL in. 

sys.path.append(r"E:\Source\spikes\IronPythonSpike\IronPythonSpike\bin\debug") 

From here we can use the clr object to add a reference to our C# middle tier assembly.  This assembly of course provides our domain objects.  From there its just a matter of randomly generating the customer and address attributes from a predefined list of possibilities: names, streets, states.

Certainly you could create a separate generator script which would provide for much more varied data, you could even pull these bits from another database or even a web service.  You could even write the script so that the data was not random but always the same.  For my purposes though, this works just fine.  A more realistic domain would have more validation rules and would probably require a more intelligent script.

To verify that everything was added to the repository I can just make a quick call at the end of the script

for c in repository.GetAll():
	print c.ToString()
	print ""

Which on this run prints out:

Tim Tim
959 Lonely Lane
AL, 96094

John Pat
19577 Pacific Ave.
FL, 62699

Pat John
2194 Lonely Lane
OR, 58176

Smith Neal
6430 Pacific Ave.
AL, 88910

Jones John
11059 Pacific Ave.
TX, 67800

Smith Smith
24162 6th Ave.
CA, 81493

Neal Hank
4054 Pacific Ave.
WA, 33392

Smith Jones
32012 Pacific Ave.
FL, 44461

Tim Hank
28812 Foobar Ct.
AL, 98069

Neal Joe
1751 Main St.
NV, 52048

Not bad for a few lines of script!

I think the important part to remember is that we're using the middle tier to load data complete with validation and any other business logic that normally executes on save, all the while keeping things flexible and lightweight.

Sunday, November 02, 2008 11:50:23 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  |