Replies: 5 comments 12 replies
|
This is extremely simple to implement e.g. we are using this The loop is backwards so that A compiler support will be needed for true string interpolation like in this C# sample |
|
There also some VBA answers here: I use Public Function printf(ByVal mask As String, ParamArray tokens() As Variant) As String
Dim i As Long
For i = 0 To UBound(tokens)
Dim escapedToken As String
escapedToken = Replace$(tokens(i), "}", "\}") 'only need to replace closing bracket since {i\} is already invalid
If InStr(1, mask, "{}") <> 0 Then
'use positional mode {}
mask = Replace$(mask, "{}", escapedToken, Count:=1)
Else
'use indexed mode {i}
mask = Replace$(mask, "{" & i & "}", escapedToken)
End If
Next
mask = Replace$(mask, "\}", "}")
printf = mask
End Functionsince it allows you not to number the substitutions ( |
|
Doing substitutions covers a lot of cases but is never clean. For example in the solution provided by @wqweto if we try something like: Printf("Hello %1 or %%2", "John", "1 Clare")then we get Same with the solution provided by @Greedquest , and as it can be seen in the link he provided (as a note) something like The only way to be sure there are no unexpected edge cases is to parse the mask. It can be done character by character or as a split. For example, updating the '%' solution to be safe using a split approach could look like: Public Function Printf(ByVal mask As String, ParamArray tokens() As Variant) As String
Dim parts() As String: parts = Split(mask, "%")
Dim i As Long
Dim j As Long
Dim isFound As Boolean
Dim s As String
'
'Always ignore first part - covers if mask started or not with %
For i = LBound(parts) + 1 To UBound(parts)
If LenB(parts(i)) = 0 Then
parts(i) = "%"
Else
isFound = False
For j = UBound(tokens) To LBound(tokens) Step -1
s = CStr(j + 1)
If Left$(parts(i), Len(s)) = s Then
parts(i) = tokens(j) & Right$(parts(i), Len(parts(i)) - Len(s))
isFound = True
Exit For
End If
Next j
If Not isFound Then
parts(i) = "%" & parts(i)
End If
End If
Next i
Printf = Join(parts, vbNullString)
End Functionwhich is more efficient if the tokens have a lot of % characters or slower if the mask has a lot of % characters but most importantly is correct. |
|
Thanks all for your replies and alternative solutions. Instead of debating so much why not request @WaynePhillipsEA to add a function in the compiler to achieve this in a robust manner. One cannot expect a fresh graduate out of school (or a newbie to tB) to be able to build such a complex function so it should be available by default as a builtin function. Actually this and many such functions and procedures if provided out-of-the-box in tB will draw new developers towards it. |
|
I'm not seeing significant value in having the compiler do string interpolation. Substitution of a field marker in a string by a variable can readily be achieved through a library. I know some languages now allow substitution by variable name, but I think in the long run this adds less value than you think, particularly when you want to start formatting the appearance of an interpolated variable. So my vote, if we are voting, is for string interpolation to be a library which can be written and policed by us users, rather than a diversion from getting a good compiler. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Give a function called either StringBuilder or StringFormatter for building complex strings using place holders.
It syntax would be something like this:
<Result> = StringBuilder(<ActualString> [, <Parameter 1> [... [, <Parameter N>]]])Here ActualString is a string with place holders for example -
"The age of patient - %1 is %2 and has been diagnosed with %3"Parameter 1are the actual values that are to be replaced in the ActualString.Sample usage:
Here there is one cache and that is that the number of place holders and parameters should match in number.
All reactions