Android Tutorial [B4X] Smart String Literal

The "smart string" literal is a more powerful version of the standard string literal.
It has three advantages:
  1. Supports multi-line strings.
  2. No need to escape quotes.
  3. Supports string interpolation.
The smart string literal starts with $" and ends with "$.
Examples:
B4X:
Dim s As String = $"Hello world"$
Dim query As String = $"
SELECT value_id FROM table3
WHERE rowid >= random()%(SELECT max(rowid)FROM table3)
AND second_value ISNOTNULL
LIMIT 1"$
Log($"No need to escape "quotes"! "$)

String Interpolation

Smart strings can hold zero or more placeholders with code. The placeholders can be easily formatted.
A placeholder starts with $[optional formatter]{ and ends with }:
B4X:
Log($"5 * 3 = ${5 * 3}"$) '5 * 3 = 15
You can put any code you like inside the placeholders.
B4X:
Dim x = 1, y = 2, z = 4 As Int
Log($"x = ${x}, y = ${y}, z = ${Sin(z)}"$) 'x = 1, y = 2, z = -0.7568024953079282

This is a compile time feature. You cannot load the strings from a file for example.

Number Formatter

The number formatter allows you to set the minimum number of integers and the maximum number of fractions digits. It is similar to NumberFormat keyword.

The number formatter structure: MinIntegers.MaxFractions. MaxFractions component is optional.
Examples:
B4X:
Dim h = 2, m = 15, s = 7 As Int
Log($"Remaining time $2{h}:$2{m}:$2{s}"$) 'Remaining time 02:15:07
Log($"10 / 7 = $0.3{10 / 7}"$) '10 / 7 = 1.429
Log($"$1.2{"The value is not a number!"}"$) 'NaN

Other Formatters

Note that the formatters are case insensitive.
Date - Equivalent to DateTime.Date:
B4X:
Log($"Current date is $date{DateTime.Now}"$) 'Current date is 02/02/2015

Time - Equivalent to DateTime.Time:
B4X:
Log($"Current time is $time{DateTime.Now}"$) 'Current time is 11:17:45

DateTime - Equivalent to DateTime.Date & " " & DateTime.Time:
B4X:
Log($"Current time is $DateTime{DateTime.Now}"$) 'Current time is 02/02/2015 11:18:36

XML - Escapes the five XML entities (", ', <, >, &):
B4X:
Dim UserString As String = $"will it break your parser ><'"&?"$
Log($"User input is: $xml{UserString}"$)
'User input is: will it break your parser &gt;&lt;&#39;&quot;&amp;?
This is also useful for html content.
 
Last edited:

thedesolatesoul

Expert
Licensed User
Longtime User
Nice.
This is a compile time feature. You cannot load the strings from a file for example.
Can you elaborate on this?
Can we assign a string like:
B4X:
Dim str as String = $"The value of x is ${x}"$
Log(str)
Is the string substitution done at compile time, so it will replace ${x} with the value of x within the string?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Can we assign a string like:
Yes. This code will work.

You can think of it as if the compiler replaces this: $"The value of x is ${x}"$
with:
B4X:
"The value of x is " & x

If you try to load this string from a file then the string interpolation feature will not work and the string will return as is.

It is simpler than it might seem...
 

Troberg

Well-Known Member
Licensed User
Longtime User
Cool!

What are the syntax coloring options for this?

I usually have a light grey background for string literals and numbers, it makes them into nice little boxes and it's easy for the eye to see what's part of them and what's not, which is useful when you have a long line which concatenates string literals with variables and function call return values.

For these smart strings, I can see the reverse problem: it can be difficult to see the placeholders/formatters. Once again, having the proper options for syntax coloring will make this easy.

Edit: Syntax coloring also gives a hint of what the compiler will make of it, allowing you to easier catch stuff like mismatched/misplaced quotes.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
What are the syntax coloring options for this?
The string is the same color as other strings. The placeholders are treated like any other code.

Is the process of evaluating a string literal containing one or more place holders, yielding a result in which the place holders are replaced with their corresponding values
Yes.
 

Ho Chia Leung

Member
Licensed User
Longtime User
Hi Erel,

First of all. Thanks for this awesome feature. It keeps my code clean and tidy. However I've found some bugs on it, something like this
B4X:
Dim item_quantity as Int
Dim item_price as double
Dim subtotal as double
Dim total as string

item_quantity = 5
item_price = 3.5
subtotal = item_quantity*item_price

total = $"${item_quantity} x $1.2{item_price} = $1.2{subtotal}"$

'but the output I get is

'{item_quantity} x 3.5 = 17.5

'why it showed {item_quantity} instead of 5?

And 1 more thing, is there anyway to use this for Minimum Fraction instead of maximum? I am looking for some easy way to format the numbers to like 17.50.

Thank you
 

Troberg

Well-Known Member
Licensed User
Longtime User
'why it showed {item_quantity} instead of 5?[/CODE]

My guess is that, when parsing the code, the compiler somehow misinterprets $"$, as "$ is also the end marker for smart strings. Try changing the line to (added a space at the beginning of the string to break up the unintentional "$):

B4X:
total = $" ${item_quantity} x $1.2{item_price} = $1.2{subtotal}"$

Still a bug, but if I'm right, at least we've got it pinpointed.
 

Ho Chia Leung

Member
Licensed User
Longtime User
My guess is that, when parsing the code, the compiler somehow misinterprets $"$, as "$ is also the end marker for smart strings. Try changing the line to (added a space at the beginning of the string to break up the unintentional "$):

B4X:
total = $" ${item_quantity} x $1.2{item_price} = $1.2{subtotal}"$

Still a bug, but if I'm right, at least we've got it pinpointed.

Actually I tried that, but the result is still the same. I tried $" $1.2{item_quantity} ... "$ also, and I still get the same string.

But when I try open a new project, put the same code, I got the result I was expecting, which is 5 x 13.5

So strange o_Oo_O
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm unable to reproduce it.

Tested with this code:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim item_quantity As Int
   Dim item_price As Double
   Dim subtotal As Double
   Dim total As String
   item_quantity = 5
   item_price = 3.5
   subtotal = item_quantity*item_price
   total = $"${item_quantity} x $1.2{item_price} = $1.2{subtotal}"$
   Log(total)
End Sub
And 1 more thing, is there anyway to use this for Minimum Fraction instead of maximum?
You will need to use NumberFormat2 inside the placeholder.
 

Ho Chia Leung

Member
Licensed User
Longtime User
I'm unable to reproduce it.

Tested with this code:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim item_quantity As Int
   Dim item_price As Double
   Dim subtotal As Double
   Dim total As String
   item_quantity = 5
   item_price = 3.5
   subtotal = item_quantity*item_price
   total = $"${item_quantity} x $1.2{item_price} = $1.2{subtotal}"$
   Log(total)
End Sub

You will need to use NumberFormat2 inside the placeholder.
Thanks for the reply Erel.

Anyway, I am not able to reproduce this issue now as well.. Something went strange last night hmm. Anyway thanks for it :D. Cheers
 

zyblux

Member
Licensed User
Longtime User
Hi Erel,
The Multi-Line / HEREDOC type strings and String Interpolation & formatters are very nice additions, these were some of my favourite features in Ruby. When will a new version of B4J be released so I can use them? :)

BTW: Thank you for creating such wonderful products. I'm very new to the B4X family, I only took the plunge a few weeks ago and decided to buy B4A after a few short hours of trying it. You have re-kindled the fire inside an old-ish, but very jaded developer who misses the happy days of VB6, who has been warped by .NET, C++ and various scripting languages over the years. I've not felt as productive nor excited being knee deep in code for 10+ years. And it's all thanks to B4X; it's amazing language that truly makes you smile, superb IDE that's a joy to use, wonderful libraries and a very lively and incredibly creative community.

Cheers Everyone :D

p.s. You really should charge for B4J (at least for the next big release). I actually feel guilty about using something so darn good and you not being financially rewarded for it. But I will definitely donate and contribute to the community ASAP.
 

zyblux

Member
Licensed User
Longtime User
Brilliant - thanks, I tried the other day and it cleaned up my code very nicely :)
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Date - Equivalent to DateTime.Date:
I beg your pardon because I had no time to try the beta so I don't know if the case is already handled about.
Have you thought about a way to control the returned date formated ? (I mean dd/mm/yyyy) or is it a fixed format or based on the current locales ?

Just a thought
 

DonManfred

Expert
Licensed User
Longtime User
based on the current locales
i think the actual settings will be used... Set DateTime.DateFormat and DateTime.TimeFormat to the values you want and then use the literal string.
At the end of your sub you can restore the default values
B4X:
    DateTime.DateFormat = DateTime.DeviceDefaultDateFormat
    DateTime.TimeFormat = DateTime.DeviceDefaultTimeFormat
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
i think the actual settings will be used.
You know what : I am a stupid brain ! I have thought that I had to use the DateFormat each time I wanted a Date string ... Stupid me.
Thanks a lot Manfred
 

CyclopDroid

Well-Known Member
Licensed User
Longtime User
What is the problem?


B4X:
Sub tic_tick
Log($"Current time is $time{DateTime.Now}"$)
tempo.Text=$"Sono le ore: $time{DateTime.Now}"$
Dim percent=(DateTime.GetHour(DateTime.Now)*60*60)+(DateTime.Getminute(DateTime.Now)*60)+DateTime.Getsecond(DateTime.Now) As Double
percent=(percent/86400)*100
percentuale.Text=$"Percentuale Giorno: $2(percent) %"$

Log($"Percentuale Giorno: $2(percent) %"$)

tempo.Left=(Panel1.Width/2)-(tempo.Width/2)
tempo.Top=(Panel1.Height/2)-(tempo.Height/2)
percentuale.Left=(Panel1.Width/2)-(percentuale.Width/2)
percentuale.Top=tempo.Top+10%y
End Sub

the result is:

Percentuale Giorno: $2(percent) %

into Label View (Percentuale) ad into Log. :confused:
 
Last edited:
Top