Power6: __CALLER_MEMBER__

[This post is part of a series, "wish-list for future versions of VB"]

 

IDEA: Reflect on your caller with __CALLER_MEMBER__ . Introduce three new "optional parameter defaults" which are called __CALLER_FILE__, __CALLER_LINE__ and __CALLER_MEMBER__. (The names are ugly! We'd like suggestions for better ones!) If a callsite doesn't provide an argument, then the compiler files it out with the appropriate string/integer/MethodInfo as appropriate.

 

SCENARIO: You want to write a "log" function, like you did in C++ macros, which prints the current file and line number. This code shows how you might do it. Note how useful it is to have them as "optional parameter defaults". It lets us write a wrapper function "log(e As Exception)" which passes its caller's information on down to the underlying function "log(s As String)".

    Sub log(s As String,
Optional file As String = __CALLER_FILE__,

            Optional line As Integer = __CALLER_LINE__,
            Optional caller As MethodInfo = __CALLER_MEMBER__)

        My.Computer.FileSystem.WriteAllText("c:\log.txt",
String.Format("{0}:{1}#{2} - {3}{4}", file, caller.Name, line, s, vbCrLf),
True)

    End Sub

    Sub log(e As Exception,
Optional file As String = __CALLER_FILE__,
Optional line As Integer = __CALLER_LINE__,
Optional caller As MethodInfo = __CALLER_MEMBER__)

        log(e.Message, file, line, caller)

    End Sub

 

SCENARIO: You want to save boilerplate code in your property templates, and want to be able to write a general-purpose function "GetMyName()" which returns the name of the property. Currently the best you can do is call MethodBase.GetCurrentMethod. But this feature would allow something more elegant:

    WriteOnly Property p As Integer

        Set(ByVal value As Integer)

            Dim propName = GetMyName()

            log(propName & ":=" & value)

        End Set

    End Property

    Function GetMyName(Optional ByVal caller As MethodInfo = __CALLER_MEMBER__) As String

        If Not caller.IsSpecialName Then Return caller.Name

        Dim prop = (From p In caller.DeclaringType.GetProperties() Where p.GetAccessors().Contains(caller)).FirstOrDefault

        If prop IsNot Nothing Then Return prop.Name

        Return caller.Name

    End Function

 

 

Provisional evaluation from VB team: On the one hand, this looks like it'd help a common scenario. On the other hand, it feels like a hack. Also note that it'd be impossible to make it work with late-bound dispatch. Please chime in with your opinions. Do you like this? Can you see other scenarios for it? We think the idea is only worth considering if we here more compelling scenarios, or more compelling demand from users.