I am working an a more meaningful way to print objects in VBA. The desired result should look something like this.
Console.PrintLine List.Create(1, 2, 3) List(1, 2, 3)
The concept is that objects implementing an
IPrintable interface are printed as their
ToString property. Primitive data types are printed as is
Console.PrintLine "a" a
And other objects are represented as "TypeName(&ObjPtr)"
Console.PrintLine New Collection Collection(&150653720)
But the issue that is gunking up my design is that I want nested objects to represent themselves
Console.PrintLine List.Create(1, List.Create(), New Collection) List(1, List(), Collection(&150653384))
My solution is to use an auxiliary helper methods, located in a standard module called
cast, which in a way provides a default implementation of
Public Function ToString(ByVal x As Variant) As String Dim result As String If TypeOf x Is IPrintable Then result = x.ToString ElseIf IsObject(x) Then result = DefaultObjectToString(x) Else result = CStr(x) End If ToString = result End Function Private Function DefaultObjectToString(ByVal x As Object) As String DefaultObjectToString = ObjectToString(x, cast.CArray(Array("&" & ObjPtr(x)))) End Function Public Function ObjectToString(ByVal o As Object, ByRef members() As Variant, _ Optional ByVal delim As String = ", ") As String Dim stringMembers() As String If LBound(members) <= UBound(members) Then ReDim stringMembers(LBound(members) To UBound(members)) End If Dim i As Long For i = LBound(members) To UBound(members) stringMembers(i) = ToString(members(i)) Next i ObjectToString = TypeName(o) & "(" & Join(stringMembers, delim) & ")" End Function
I would want this to be located in the
IPrintable class but that must be empty to use it as an interface.
Now any method that is printing the objects can just use
cast.ToString like console does
Public Sub PrintLine(Optional ByVal x As Variant) If IsMissing(x) Then Debug.Print vbNullString Else Debug.Print cast.ToString(x) End If End Sub
Also here is how
ToArray is just an array version of the list.)
Public Property Get ToString(Optional delim As String = ", ") As String ToString = cast.ObjectToString(Me, ToArray, delim) End Property Public Property Get IPrintable_ToString() As String IPrintable_ToString = ToString() End Property
If I had a BinaryTree object it would look like this.
Public Property Get ToString() As String ToString = cast.ObjectToString(Me, Array(LeftTree, RightTree), ", ") End Property