Ok, to be honest, this is going to be a pretty lightweight post as it's about a simple little string function in BoxLang, but as I discovered it rather recently and was intrigued by what it did.

So first off - how did I find this? In the BoxLang docs, there's a whole section on built-in functions and a subcategory just for string. I was looking it over and realized there were quite a few that I had not known existed. There are some interesting ones in there like pascalCase and snakeCase. I was pretty sure I knew exactly how these worked, but I went ahead and built a quick demo that demonstrates both:

Ok, that works well enough, but let's talk StringBind. StringBind lets you create a string that acts as a template, letting you pass data and re-evaluate the result every time.

Now, on one hand, you may be wondering why that's necessary, as BoxLang already has a template language support baked in. As a trivial example:

name = "Raymond";
age = 52;

println("My name is #name# and I am #age# years old.");

This works, but is also a one time operation. What I mean is, as soon as you use that string (in my case I printed it, but I could have saved it as well), you can't re-evaluate it. Now typically that also isn't necessary an issue, as you can simply keep creating new versions in a loop or some such:

people = [{name:"Raymond", age:52}, {name:"Lindy", age: 45}];

people.each(p => println("My name is #p.name# and I am #p.age# years old."));

But what StringBind gives us is a more abstract way to create a template and re-use it. It begins with a different definition of variable tokens. Instead of pound signs, you wrap tokens with ${name} where the item inside represents a token named name. You can also define tokens with default values, ${name:Nameless}. The name of your token doesn't necessarily need to a valid variable name, so for example, this is allowed as well: ${full name}, which could perhaps be more readable than fullName.

Using this feature requires you to define the template, duh, and than call it with stringBind where you'll pass the template and data:

str  = """
This is a big string with ${name} and ${age}. My favorite food is ${food:sushi}.
"""

s = stringBind(str, {
  "name":"Ray",
  "age":52
})

The template is passed first, the structure of data second. Note that I didn't pass food so it should default. The result is as you expect: This is a big string with Ray and 52. My favorite food is sushi.. Obviously passing food will change the result:

s = stringBind(str, {
  "name":"Ray",
  "age":52,
  "food":"nature valley bars"
})

println(s);

This gives: This is a big string with Ray and 52. My favorite food is nature valley bars.

You can try this yourself below:

Ok, so fair enough to say, this is one of those functions I don't see using day to day, but I thought it was a pretty cool idea and something I want to keep in my (BoxLang-ified) tool belt for use later. What do people think? I'd love to hear some ideas of how this could be useful, so leave me a comment below!

Photo by Steven Van Elk on Unsplash