Android Tutorial [B4X] Smart String Literal

Discussion in 'Tutorials & Examples' started by Erel, Feb 2, 2015.

  1. Erel

    Erel Administrator Staff Member Licensed User

    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:
    Code:
    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 }:
    Code:
    Log($"5 * 3 = ${5 * 3}"$'5 * 3 = 15
    You can put any code you like inside the placeholders.
    Code:
    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:
    Code:
    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:
    Code:
    Log($"Current date is $date{DateTime.Now}"$'Current date is 02/02/2015
    Time - Equivalent to DateTime.Time:
    Code:
    Log($"Current time is $time{DateTime.Now}"$'Current time is 11:17:45
    DateTime - Equivalent to DateTime.Date & " " & DateTime.Time:
    Code:
    Log($"Current time is $DateTime{DateTime.Now}"$'Current time is 02/02/2015 11:18:36
    XML - Escapes the five XML entities (", ', <, >, &):
    Code:
    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: Dec 8, 2016
  2. Devv

    Devv Active Member Licensed User

    Nice work bro..
    when 4.3 will be available ?
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    The beta version will be soon available.
     
  4. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Nice.
    Can you elaborate on this?
    Can we assign a string like:
    Code:
    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?
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    Yes. This code will work.

    You can think of it as if the compiler replaces this: $"The value of x is ${x}"$
    with:
    Code:
    "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...
     
  6. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Ok, this makes a lot more sense now.
    Thanks.
     
  7. Troberg

    Troberg Well-Known Member Licensed 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: Feb 2, 2015
  8. Erel

    Erel Administrator Staff Member Licensed User

    The string is the same color as other strings. The placeholders are treated like any other code.

    Yes.
     
  9. Ho Chia Leung

    Ho Chia Leung Member Licensed 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
    Code:
    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
     
  10. Troberg

    Troberg Well-Known Member Licensed 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 "$):

    Code:
    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.
     
  11. Ho Chia Leung

    Ho Chia Leung Member Licensed User

    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
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    I'm unable to reproduce it.

    Tested with this code:
    Code:
    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.
     
  13. Ho Chia Leung

    Ho Chia Leung Member Licensed User

    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
     
  14. zyblux

    zyblux Member Licensed 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.
     
  15. Erel

    Erel Administrator Staff Member Licensed User

    Thank you :)
    The latest beta version of B4J supports this feature.
     
  16. zyblux

    zyblux Member Licensed User

    Brilliant - thanks, I tried the other day and it cleaned up my code very nicely :)
     
  17. lemonisdead

    lemonisdead Well-Known Member Licensed User

    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
     
  18. DonManfred

    DonManfred Expert Licensed User

    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
    Code:
    DateTime.DateFormat = DateTime.DeviceDefaultDateFormat
        
    DateTime.TimeFormat = DateTime.DeviceDefaultTimeFormat
     
    MarcoRome and lemonisdead like this.
  19. lemonisdead

    lemonisdead Well-Known Member Licensed User

    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
     
  20. JakeBullet70

    JakeBullet70 Well-Known Member Licensed User

    Ouch... This hurts... LOL
     
    lemonisdead likes this.
Loading...