string interpolation

Started by Thomas Bock, November 15, 2023, 08:45:15 AM

Previous topic - Next topic

Thomas Bock

In C# there is the possibility to build strings by referencing/including variables.

string name = "Tom";
var date = DateTime.Now;
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");


These strings are much more readable than coding a concatenation of several small strings. E.g. building a SQL-statement becomes more straight forward.
If PxPlus would provide such functionality, we could gain speed, because the interpreter would not need to translate several lines of code.

Devon Austen

Here is an example of your code in PxPlus:


name$ = "Tom"
print "Hello, "+name$+"! Today is "+dte(0:"%Wl")+", it's "+dte(0:"%Hz:%mz")+" now."


Concatenation can happen on the same line of code.

As for speed I don't think the $"xxxx {var} xxxx" style string building would be any faster from a performance standpoint. Internally the same thing will be happening building the string plus now you have to scan the string for the variables as well.

Does that syntax work for you?
Principal Software Engineer for PVX Plus Technologies LTD.

Allen Miglore

I agree, this is a handy feature of many languages.  I wrote a function to do something similar a while back and use it internally in UnForm.

def fn%resolveexpr$(local s$)
   local x,expr$,before$,after$,val$,between$
   s$=sub(s$,"\{",$01$),s$=sub(s$,"\}",$02$)
   x=msk(s$,"{[^{}]*}")
   while x>0
      before$=s$(1,x-1),between$=s$(x+1,msl-2),expr$="str("+s$(x+1,msl-2)+")",after$=s$(x+msl)
      val$=$01$+between$+$02$,val$=evs(expr$,err=*next)
      s$=before$+val$+after$
      x=msk(s$,"{[^{}]*}")
   wend
   s$=sub(s$,$01$,"{"),s$=sub(s$,$02$,"}")
   return s$
end def

It works with anything that can be resolved with evs().

a=123, b$="456"

?fn%resolveexpr$("This is a: {str(a:""###0.00"")}, this is b$: {b$}")
This is a:  123.00, this is b$: 456

Internal braces can be escaped:

?fn%resolveexpr$("This is a: {str(a:""###0.00"")}, this is b$: \{b$\}")
This is a:  123.00, this is b$: {b$}


Stéphane Devouard

Thomas

String interpolation exists (kinda) in PxPlus :

print MSG(="Hello, %1 ! Today is %2, it's %3 now.",name$,dte(0:"%Wl"),dte(0:"%Hz:%mz"))
Stéphane Devouard
Portfolio | Work

Mike King

Actually here is a simple object that you can use to accomplish what you are looking for:

  def class "string"
  function perform Eval$(string$)
  local _.x$,_.o
  enter (_.x$)
  _.o=pos("\"=_.x$)
  if _.o \
   then _.x$=sub(_.x$,"\{",$01$);
        _.x$=sub(_.x$,"\}",$02$);
        _.x$=sub(_.x$,"\"+quo,$03$)
!
  translate _.x$,"{"+chr(6)+"""+STR("+"}"+chr(3)+")+"""
  _.x$=evs(quo+_.x$+quo)
  if _.o \
   then translate _.x$,$01$+chr(1)+"{"+$02$+chr(1)+"}"+$03$+chr(1)+quo
  return _.x$
  end def


Basically you can pass it a string with values/expressions to expand surrounded by curly braces.  If you want to input actual curly braces or a quote in the output string, prefix them with a backslash.  For example:

->name$="Tom"
->o=new("string")
->print o'Eval$("Hello, {name$}! Today is {day}")
Hello, Tom! Today is 12/14/23


If the string has an error such as unmatched curly braces or a invalid value/expression the error will be returned to the caller.
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com