BooDesign By Contract in 20 lines of code

time to read 2 min | 225 words

Now, before Greg hurls a modopt on me, I want to be clear that this isn't the same thing that Spec# is doing. But it is a very cool way to specify constraints that must always be valid when a method exists.

Here is the code:

[AttributeUsage(AttributeTargets.Class)]
class EnsureAttribute(AbstractAstAttribute):
	
	expr as Expression
	
	def constructor(expr as Expression):
		self.expr = expr
		
	def Apply(target as Node):
		type as ClassDefinition = target
		for member in type.Members:
			method = member as Method
			continue if method is null
			block = method.Body
			method.Body = [|
				block:
					try:
						$block
					ensure:
						assert $expr
			|].Block

And the usage:

[ensure(name is not null)]
class Customer:
	name as string
		
	def constructor(name as string):
		self.name = name
	
	def SetName(newName as string):
		name = newName

Now, any attempt to set the name to null will cause an assertion exception. This technique is quite powerful, and very easy to use. A few years ago I wrote a design by contract implementation for boo that was far more ambitious (handling inheritance, etc). I remember it being much more complicated, and while things like quasi quotation do make it easier, it is not that big a change.

I think that mostly it is the way I write code now, striving to simplicity is something that I am trying to apply recently, and I think it works.

More posts in "Boo" series:

  1. (05 Nov 2009) The Wheel of Time – The Gathering Storm
  2. (11 Aug 2009) Yellow Eyes
  3. (24 Jul 2009) Watch on the Rhine
  4. (23 Jul 2009) By Heresies Distressed
  5. (23 Jul 2008) By Schism Rent Asunder
  6. (04 Oct 2007) Making Money
  7. (30 Sep 2007) Empire of Ivory
  8. (08 Sep 2007) Empire Of Man
  9. (01 Sep 2007) March Upcountry
  10. (21 Feb 2007) Programming WCF Services
  11. (09 Feb 2007) Windows Developer Power Tools
  12. (25 Sep 2006) Old Man's War
  13. (03 Sep 2006) His Majesty's Dragon / Throne of Jade / Black Powder War
  14. (30 Aug 2006) Applying Domain-Driven Design and Patterns
  15. (18 Aug 2006) Dzur
  16. (15 Aug 2006) When Darkness Falls
  17. (22 Apr 2006) Data Binding with Windows Forms 2.0
  18. (17 Oct 2005) Knife Of Dreams
  19. (28 Aug 2005) Working Effectively With Legacy Code
  20. (25 Jul 2005) Harry Potter and the Half-Blood Prince
  21. (14 Jul 2005) Sword of Ice
  22. (14 Jul 2005) Vows & Honor Trilogy
  23. (14 Jul 2005) The Mage Storms Trilogy
  24. (14 Jul 2005) Winds of Change
  25. (10 Jul 2005) Winds of Change
  26. (09 Jul 2005) Winds Of Fate
  27. (08 Jul 2005) Burning Water
  28. (08 Jul 2005) By The Sword
  29. (06 Jun 2005) Developer To Designer
  30. (05 Jun 2005) The Last Herald Mage
  31. (01 Jun 2005) Arrow's Fall
  32. (01 Jun 2005) Arrow's Flight
  33. (27 Apr 2005) Domain Driven Desing
  34. (01 Apr 2005) Exile's Valor
  35. (18 Jan 2005) Alta
  36. (16 Jan 2005) Coding Slave
  37. (13 Jan 2005) Hibernate In Action
  38. (25 Oct 2004) In Search of Stupidity