Wednesday, March 08, 2006

Excelagility - Part II - Printing out objects with external polymorphism

Where we explore how to get rid of some of the verbose bureaucracy of VBA and how to create uniformity using 'Verbs' and external polymorphism..


Excelagility

- or -  

How to Shape Excel with VBA into a Legible Expressive Agile Platform

~

V. 0.0.2

Printing Out Objects

Now we have objects, but it's not easy to print them out to screen, for example for debugging purposes.

We can do this by providing each class which is of interest to us with a method that converts it to string: a 'toString' method.

 

Dim a_person As Person

Set a_person = Person("John","Smith",#23/11/1980#)

 

Debug.Print a_person.toString

 

Let's add such a method to the 'Person' class:

 

Function toString() As String

toString = "Person(" & _

           Me.Name & ", " & _

           Me.Surname & ", " & _

           Me.DateOfBirth & ") "

End Function

 

Now you can easily print out a Person object to the Immediate Window.

However, having to write 'Debug.Print' and 'toString' is quite verbose and we can devise a way to make this more readable.

 

Sub puts(an_entity)

Debug.Print strize(an_entity)

End Sub

 

The new 'puts' command substitutes the lengthy 'Debug.Print' command and it also forces the argument passed to it to be converted to a string.  The actual conversion is performed by the 'strize' (short for string-ize) function.

The code for the 'strize' function employs a technique that I call 'external polymorphism' to handle entities of any type and not only Objects.

 

Function strize(an_entity) As String

If IsObject(an_entity) Then

     strize = an_entity.toString

Else

     strize = CStr(an_entity)

End If

End Function

 

This code now allows you to write much more expressive statements:

 

Dim a_person As Person

Set a_person = Person("John","Smith",#23/11/1980#)

 

puts a_person

puts a_person.DateOfBirth

puts a_person.Name

 

The 'puts' command, however, is not as robust as we would like it to be.  If you pass it an object that does not implement the 'toString' method, then it will fail without providing much of an explanation.  We can make it more robust by adding some simple error handling:

 

Function strize(an_entity) As String

On Error Goto cannot_convert_to_string

     If IsObject(an_entity) Then

          strize = an_entity.toString

     Else

          strize = CStr(an_entity)

     End If

Exit Function

 

cannot_convert_to_string:

     strize = TypeName(an_entity)

End Function

 

If the entity passed cannot be converted to string, then we recover by returning simply the type name of the entity.  Alternatively we may want it to return an error message, using the 'MsgBox' command.




Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?