When is it suitable to use a Sub-Procedure instead of a function?

Viewed 113

In my class today I was told change some of my sub-procedures to functions, and when I asked why it's better my teacher struggled to answer, generally, i've always thought that functions should only really be used when a value is returned. In the two examples below; is there one method that should be used over the other, or does it not matter? And if it does matter why? Thanks in advance.

Method 1 (Sub-Proc):

Sub EncryptString(ByVal unkString, ByRef encryptedString)
    For i = 1 To Len(unkString)
        encryptedString += "*"
    Next
End Sub

Method 2 (Function): [In main I assign the variable "encryptedString" to this function].

Function encryptString(ByVal unkString) As String
    For i = 1 To Len(unkString)
        encryptString += "*"
    Next
End Function
3 Answers

You've misunderstood what they're trying to tell you. In your Function example there is no difference. What your teacher is expecting is like this:

Function EncryptString(ByVal unkString) As String
    Dim encryptedString As String = ""
    For i = 1 To Len(unkString)
        encryptedString += "*"
    Next
    Return encryptedString
End Function

This is a cleaner and more reusable way than modifying a field, an argument passed ByRef, or the underlying variable of the function

Your example show one of the multiple reason, who initialize the data is unclear. With your sample code, the first option would append to the passed string while the second would create a new string.

The first method would have to specify if it needs an empty string or explain why it appends. While the second method clearly show that a new string will be returned.

Sub Main()

    Dim u, e As String

    u = "123"
    e = "123"

    EncryptString1(u, e)
    Console.WriteLine(e) ' Display: 123***

    u = "123"
    e = "123"

    e = encryptString2(u)
    Console.WriteLine(e) ' Display: ***

    Console.ReadLine()

End Sub
Sub EncryptString1(ByVal unkString As String, ByRef encryptedString As String)
    For i As Integer = 1 To Len(unkString)
        encryptedString += "*"
    Next
End Sub

Function encryptString2(ByVal unkString As String) As String
    encryptString2 = ""
    For i As Integer = 1 To Len(unkString)
        encryptString2 += "*"
    Next
End Function

Please have option strict on. Also, personally, I rather create a variable instead of using the function name, use .Length instead of Len() and concatenate with & instead of +.

Function encryptString3(ByVal unkString As String) As String
    Dim encryptedString As String = ""

    For i As Integer = 1 To unkString.Length
        encryptedString &= "*"
    Next

    Return encryptedString
End Function

Or just use the New operator of the String class.

Dim encryptedString as New String("*"c, unkString.Length)

Well, when I was learning this stuff, it was always to use functions to calculate values and subs to do other stuff. I guess for something very general, it doesn't really matter which methodology you use, as you have illustrated in your example. See the link below for further discussion on this topic.

http://analystcave.com/vba-function-vs-vba-sub-procedures/

Related