Skip to main content
Code Review

Return to Question

Commonmark migration
Source Link

###Examples

Examples

###Examples

Examples

Tweeted twitter.com/StackCodeReview/status/1207495889155239943
Update broken links
Source Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36

Predeclared Class: TwoWayMapping TwoWayMapping

Predeclared Class: TwoWayMapping

Predeclared Class: TwoWayMapping

Whoops! Left testing code in by accident
Source Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36
'@Folder("Operator Framework.Common")
'@IgnoreModule IndexedDefaultMemberAccess: It's fine for collections I think
Option Explicit
'@PredeclaredId
Private Type mappingData
 AtoB As New Dictionary 'Use dictionary as this allows any item as key, not just strings as with collections
 BtoA As New Dictionary 'Auto-instantiate so we don't need growMapping to worry about whether the map was initialised
End Type
Public Enum gtMappingErrors
 [_ErrBase] = 1 'set to a different value for each class in a project
 mismatchedLengthError = vbObjectError + [_ErrBase]
 setsNotIterableError
 valueNotInMapError
End Enum
Private this As mappingData
Public Function Create(ByVal iterableA As Variant, ByVal iterableB As Variant) As TwoWayMapping
 With New TwoWayMapping
 .growMapping iterableA, iterableB
 Set Create = .Self
 End With
End Function
Friend Property Get Self() As TwoWayMapping
 Set Self = Me
End Property
'@Description("Create key - value pairs mapping items from A to B (and vice-versa) based on each item's index within the collection. iterableA and iterableB should be ordered iterables of equal length. Adds to existing mapping")
Public Sub growMapping(ByVal iterableA As Variant, ByVal iterableB As Variant)
 Const errorSourceName As String = "growMapping" 'CHECK
 
 'need data to be in some form that can be indexed, as For..Each only operates on one at a time
 On Error GoTo readIterableFail
 Dim aValues As Collection
 Set aValues = collectionFromIterable(iterableA)
 
 Dim bValues As Collection
 Set bValues = collectionFromIterable(iterableB)
 
 On Error GoTo cleanFail
 If aValues.Count <> bValues.Count Then raiseError mismatchedLengthError, errorSourceName
 
 Dim i As Long
 For i = 1 To aValues.Count
 this.AtoB.Add aValues(i), bValues(i)
 this.BtoA.Add bValues(i), aValues(i)
 Next i
 Debug.Print 1 / 0
 Exit Sub
 
readIterableFail:
 Const objectNotIterableError As Long = 438 'object does not support method
 Const typeNotIterableError As Long = 13 'type mismatch
 Select Case Err.Number
 Case objectNotIterableError, typeNotIterableError
 raiseError setsNotIterableError, errorSourceName
 
 Case Else
 raiseError Err.Number, errorSourceName
 
 End Select
 Resume 'comment out error raising and break here to debug
 
cleanFail:
 raiseError Err.Number, errorSourceName
 Resume 'comment out error raising and break here to debug
 
End Sub
Private Property Get collectionFromIterable(ByVal iterable As Variant) As Collection
 Dim item As Variant
 Dim result As New Collection 'auto-instantiate so we always return a valid collection, even if no members
 For Each item In iterable
 result.Add item
 Next item
 Set collectionFromIterable = result
End Property
Public Property Get AfromB(ByVal bValue As Variant) As Variant
 Const errorSourceName As String = "AfromB" 'CHECK
 If this.BtoA.Exists(bValue) Then
 Assign(AfromB) = this.BtoA(bValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Public Property Get BfromA(ByVal aValue As Variant) As Variant
 Const errorSourceName As String = "BfromA" 'CHECK
 If this.AtoB.Exists(aValue) Then 'without this check, aValue is silently added to the dictionary which is probably not what we want
 Assign(BfromA) = this.AtoB(aValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Private Sub raiseError(ByVal errNum As gtMappingErrors, Optional ByVal sourceMethod As String = vbNullString)
 Select Case errNum 'overwrite description with custom error text - case else would be keep default and rethrow error
 Case gtMappingErrors.mismatchedLengthError
 Err.Description = "iterableA and iterableB must have a 1 to 1 correspondence (i.e. must have the same length)"
 
 Case gtMappingErrors.setsNotIterableError
 Err.Description = "One of iterableA and iterableB is not iterable. For single values, wrap in Array()"
 
 Case gtMappingErrors.valueNotInMapError
 Err.Description = "That value cannot be found in the map, ensure it is of the same data type as the original keys"
 
 End Select
 'REVIEW: does Source actually do anything?
 Err.Raise errNum, Source:=IIf(sourceMethod = vbNullString, TypeName(Me), printf("{0}.{1}", TypeName(Me), sourceMethod))
End Sub

How does this look? Where can my comments be improved, or the functionality be made better - are there any methods missing? Is the error handling alright? What about organisation of code within the module?

'@Folder("Operator Framework.Common")
'@IgnoreModule IndexedDefaultMemberAccess: It's fine for collections I think
Option Explicit
'@PredeclaredId
Private Type mappingData
 AtoB As New Dictionary 'Use dictionary as this allows any item as key, not just strings as with collections
 BtoA As New Dictionary 'Auto-instantiate so we don't need growMapping to worry about whether the map was initialised
End Type
Public Enum gtMappingErrors
 [_ErrBase] = 1 'set to a different value for each class in a project
 mismatchedLengthError = vbObjectError + [_ErrBase]
 setsNotIterableError
 valueNotInMapError
End Enum
Private this As mappingData
Public Function Create(ByVal iterableA As Variant, ByVal iterableB As Variant) As TwoWayMapping
 With New TwoWayMapping
 .growMapping iterableA, iterableB
 Set Create = .Self
 End With
End Function
Friend Property Get Self() As TwoWayMapping
 Set Self = Me
End Property
'@Description("Create key - value pairs mapping items from A to B (and vice-versa) based on each item's index within the collection. iterableA and iterableB should be ordered iterables of equal length. Adds to existing mapping")
Public Sub growMapping(ByVal iterableA As Variant, ByVal iterableB As Variant)
 Const errorSourceName As String = "growMapping" 'CHECK
 
 'need data to be in some form that can be indexed, as For..Each only operates on one at a time
 On Error GoTo readIterableFail
 Dim aValues As Collection
 Set aValues = collectionFromIterable(iterableA)
 
 Dim bValues As Collection
 Set bValues = collectionFromIterable(iterableB)
 
 On Error GoTo cleanFail
 If aValues.Count <> bValues.Count Then raiseError mismatchedLengthError, errorSourceName
 
 Dim i As Long
 For i = 1 To aValues.Count
 this.AtoB.Add aValues(i), bValues(i)
 this.BtoA.Add bValues(i), aValues(i)
 Next i
 Debug.Print 1 / 0
 Exit Sub
 
readIterableFail:
 Const objectNotIterableError As Long = 438 'object does not support method
 Const typeNotIterableError As Long = 13 'type mismatch
 Select Case Err.Number
 Case objectNotIterableError, typeNotIterableError
 raiseError setsNotIterableError, errorSourceName
 
 Case Else
 raiseError Err.Number, errorSourceName
 
 End Select
 Resume 'comment out error raising and break here to debug
 
cleanFail:
 raiseError Err.Number, errorSourceName
 Resume 'comment out error raising and break here to debug
 
End Sub
Private Property Get collectionFromIterable(ByVal iterable As Variant) As Collection
 Dim item As Variant
 Dim result As New Collection 'auto-instantiate so we always return a valid collection, even if no members
 For Each item In iterable
 result.Add item
 Next item
 Set collectionFromIterable = result
End Property
Public Property Get AfromB(ByVal bValue As Variant) As Variant
 Const errorSourceName As String = "AfromB" 'CHECK
 If this.BtoA.Exists(bValue) Then
 Assign(AfromB) = this.BtoA(bValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Public Property Get BfromA(ByVal aValue As Variant) As Variant
 Const errorSourceName As String = "BfromA" 'CHECK
 If this.AtoB.Exists(aValue) Then 'without this check, aValue is silently added to the dictionary which is probably not what we want
 Assign(BfromA) = this.AtoB(aValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Private Sub raiseError(ByVal errNum As gtMappingErrors, Optional ByVal sourceMethod As String = vbNullString)
 Select Case errNum 'overwrite description with custom error text - case else would be keep default and rethrow error
 Case gtMappingErrors.mismatchedLengthError
 Err.Description = "iterableA and iterableB must have a 1 to 1 correspondence (i.e. must have the same length)"
 
 Case gtMappingErrors.setsNotIterableError
 Err.Description = "One of iterableA and iterableB is not iterable. For single values, wrap in Array()"
 
 Case gtMappingErrors.valueNotInMapError
 Err.Description = "That value cannot be found in the map, ensure it is of the same data type as the original keys"
 
 End Select
 'REVIEW: does Source actually do anything?
 Err.Raise errNum, Source:=IIf(sourceMethod = vbNullString, TypeName(Me), printf("{0}.{1}", TypeName(Me), sourceMethod))
End Sub

How does this look? Where can my comments be improved, or the functionality be made better - are there any methods missing? Is the error handling alright? What about organisation of code within the module?

'@Folder("Operator Framework.Common")
'@IgnoreModule IndexedDefaultMemberAccess: It's fine for collections I think
Option Explicit
'@PredeclaredId
Private Type mappingData
 AtoB As New Dictionary 'Use dictionary as this allows any item as key, not just strings as with collections
 BtoA As New Dictionary 'Auto-instantiate so we don't need growMapping to worry about whether the map was initialised
End Type
Public Enum gtMappingErrors
 [_ErrBase] = 1 'set to a different value for each class in a project
 mismatchedLengthError = vbObjectError + [_ErrBase]
 setsNotIterableError
 valueNotInMapError
End Enum
Private this As mappingData
Public Function Create(ByVal iterableA As Variant, ByVal iterableB As Variant) As TwoWayMapping
 With New TwoWayMapping
 .growMapping iterableA, iterableB
 Set Create = .Self
 End With
End Function
Friend Property Get Self() As TwoWayMapping
 Set Self = Me
End Property
'@Description("Create key - value pairs mapping items from A to B (and vice-versa) based on each item's index within the collection. iterableA and iterableB should be ordered iterables of equal length. Adds to existing mapping")
Public Sub growMapping(ByVal iterableA As Variant, ByVal iterableB As Variant)
 Const errorSourceName As String = "growMapping" 'CHECK
 
 'need data to be in some form that can be indexed, as For..Each only operates on one at a time
 On Error GoTo readIterableFail
 Dim aValues As Collection
 Set aValues = collectionFromIterable(iterableA)
 
 Dim bValues As Collection
 Set bValues = collectionFromIterable(iterableB)
 
 On Error GoTo cleanFail
 If aValues.Count <> bValues.Count Then raiseError mismatchedLengthError, errorSourceName
 
 Dim i As Long
 For i = 1 To aValues.Count
 this.AtoB.Add aValues(i), bValues(i)
 this.BtoA.Add bValues(i), aValues(i)
 Next i
 Exit Sub
 
readIterableFail:
 Const objectNotIterableError As Long = 438 'object does not support method
 Const typeNotIterableError As Long = 13 'type mismatch
 Select Case Err.Number
 Case objectNotIterableError, typeNotIterableError
 raiseError setsNotIterableError, errorSourceName
 
 Case Else
 raiseError Err.Number, errorSourceName
 
 End Select
 Resume 'comment out error raising and break here to debug
 
cleanFail:
 raiseError Err.Number, errorSourceName
 Resume 'comment out error raising and break here to debug
 
End Sub
Private Property Get collectionFromIterable(ByVal iterable As Variant) As Collection
 Dim item As Variant
 Dim result As New Collection 'auto-instantiate so we always return a valid collection, even if no members
 For Each item In iterable
 result.Add item
 Next item
 Set collectionFromIterable = result
End Property
Public Property Get AfromB(ByVal bValue As Variant) As Variant
 Const errorSourceName As String = "AfromB" 'CHECK
 If this.BtoA.Exists(bValue) Then
 Assign(AfromB) = this.BtoA(bValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Public Property Get BfromA(ByVal aValue As Variant) As Variant
 Const errorSourceName As String = "BfromA" 'CHECK
 If this.AtoB.Exists(aValue) Then 'without this check, aValue is silently added to the dictionary which is probably not what we want
 Assign(BfromA) = this.AtoB(aValue)
 Else
 raiseError valueNotInMapError, errorSourceName
 End If
End Property
Private Sub raiseError(ByVal errNum As gtMappingErrors, Optional ByVal sourceMethod As String = vbNullString)
 Select Case errNum 'overwrite description with custom error text - case else would be keep default and rethrow error
 Case gtMappingErrors.mismatchedLengthError
 Err.Description = "iterableA and iterableB must have a 1 to 1 correspondence (i.e. must have the same length)"
 
 Case gtMappingErrors.setsNotIterableError
 Err.Description = "One of iterableA and iterableB is not iterable. For single values, wrap in Array()"
 
 Case gtMappingErrors.valueNotInMapError
 Err.Description = "That value cannot be found in the map, ensure it is of the same data type as the original keys"
 
 End Select
 'REVIEW: does Source actually do anything?
 Err.Raise errNum, Source:=IIf(sourceMethod = vbNullString, TypeName(Me), printf("{0}.{1}", TypeName(Me), sourceMethod))
End Sub

How does this look? Where can my comments be improved, or the functionality made better - are there any methods missing? Is the error handling alright? What about organisation of code within the module?

added 292 characters in body
Source Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36
Loading
edited title
Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36
Loading
edited title
Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36
Loading
Source Link
Greedo
  • 2.6k
  • 2
  • 15
  • 36
Loading
lang-vb

AltStyle によって変換されたページ (->オリジナル) /