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