Pyro

A dynamically-typed, garbage-collected scripting language.

Version 0.16.4

String Formatting



You can use the $fmt() function to interpolate formatted values into a string:

$fmt(format_string: str, *args: any) -> str

Returns the new string created by interpolating the argument values into the format string.

A format string is a string containing {} placeholders, e.g.

var foo = $fmt("{} and {}", 123, 456);
assert foo == "123 and 456";

var bar = $fmt("{} and {}", "abc", "def");
assert bar == "abc and def";

A placeholder can be empty, as above, or it can contain an optional index and/or a format specifier.

Note that you can escape an opening brace { in a format string with a backslash, i.e. \{, to stop it being treated as a placeholder.

Indexes and Format Specifiers

A placeholder can contain a zero-based index into the argument list, e.g.

assert $fmt("{1} and {0}", 123, 456) == "456 and 123";

A placeholder can also contain a colon-prefixed format specifier, e.g.

assert $fmt("{:04d}", 123) == "0123";

If you specify both, the index comes first, e.g.

assert $fmt("{0:04d}", 123) == "0123";

Formatting Integers

You can use printf–style formatting specifiers to format i64 values, e.g.

assert $fmt("{:d}", 123) == "123";
assert $fmt("{:4d}", 123) == " 123";
assert $fmt("{:04d}", 123) == "0123";
assert $fmt("{:04x}", 123) == "007b";

The set of valid letters for i64 values is:

(Note that applying octal or hexadecimal formatting to a negative integer value returns its two's complement.)

Formatting Floats

You can use printf–style formatting specifiers to format f64 values, e.g.

assert $fmt("{:.2f}", 1.23456) == "1.23";
assert $fmt("{:5.2f}", 1.23456) == " 1.23";
assert $fmt("{:05.2f}", 1.23456) == "01.23";

The set of valid letters for f64 values is:

Formatting Runes

You can use printf–style formatting specifiers to format rune values as unsigned 32-bit integers, e.g.

assert $fmt("{:d}", 'a') == "97";
assert $fmt("{:4d}", 'a') == "  97";
assert $fmt("{:x}", 'z') == "7a";
assert $fmt("{:04x}", 'z') == "007a";

The set of valid letters for rune values is:

Using an empty format specifier for a rune is equivalent to calling $str() on the rune — i.e. it converts the rune value to a UTF-8 encoded string, e.g.

assert $fmt("{}", 'a') == "a";
assert $fmt("{}", '🔥') == "🔥";
assert $fmt("{}", '🔥') == "\xF0\x9F\x94\xA5";

Formatting Strings

You can use printf–style formatting specifiers to left- or right-pad string values, e.g.

assert $fmt("{:5}", "foo") == "  foo";
assert $fmt("{:-5}", "foo") == "foo  ";

A leading - specifies left-justification.

The decimal number specifies the minimum field width — longer strings aren't truncated, their full length is interpolated.

Custom Class Example

Here's a sample class with custom :$str(), :$debug(), and :$fmt() methods:

class Object {
    def $str() {
        return "<str>";
    }

    def $debug() {
        return "<debug>";
    }

    def $fmt(format_specifier) {
        return "<" + format_specifier + ">";
    }
}

Calling $str() on an instance returns the output of its :$str() method, e.g.

var object = Object();
assert $str(object) == "<str>";

An empty format specifier in a format string is equivalent to calling $str() on the value, e.g.

var object = Object();
assert $fmt("{}", object) == "<str>";

Calling $debug() on an instance returns the output of its :$debug() method, e.g.

var object = Object();
assert $debug(object) == "<debug>";

A format specifier consisting of a single question mark is equivalent to calling $debug() on the value, e.g.

var object = Object();
assert $fmt("{:?}", object) == "<debug>";

Otherwise, the format specifier gets passed to the value's :$fmt() method, e.g.

var object = Object();
assert $fmt("{:xyz}", object) == "<xyz>";

String Interpolation

In practice, many common use-cases for string-formatting can be handled by string-interpolation.

You can interpolate the value of an expression into a double-quoted string literal using ${}, e.g.

var value = "xyz";
assert "abc ${value} def" == `abc xyz def`;
assert "abc ${value:to_upper()} def" == `abc XYZ def`;

The syntax is:

"... ${<expression>} ..."
"... ${<expression>;<format_specifier>} ..."

You can interpolate the value of any expression into a double-quoted string literal using ${}. If the value of the expression isn't a string, it will be automatically stringified — this is equivalent to calling $str() on the value, e.g.

var value = 123;
assert "abc ${value} def" == `abc 123 def`;
assert "abc ${value + 1} def" == `abc 124 def`;

You can backslash-escape a $ symbol in a double-quoted string to prevent it being treated as the opening of an interpolated expression, e.g.

var value = 123;
assert "abc \${value} def" == `abc ${value} def`;

Interpolated expressions can be nested arbitrarily — i.e. an interpolated expression can contain a double-quoted string containing an interpolated expression containing a double-quoted string containing an interpolated expression, etc.

You can format the value of an interpolated expression by supplying a format-specifier after a semicolon, e.g.

var value = 123;
assert "${value;05d}" == `00123`;

Format-specifiers in interpolated strings have the same syntax as format-specifiers in the $fmt() function.