String Methods
Strings aren't just blobs of text — they come with a toolbox of methods you can call using dot notation. A method is like a function that belongs to a value: you write the value, a dot, the method name, and parentheses.
Think of it like giving instructions to the string itself: "Hey string, strip off your extra spaces!"
Note
Dot-notation methods work the same way on every type that supports them.
Strings and arrays both use the value.method() pattern.
Escape Sequences
Sometimes you need characters that you can't just type into a string —
like a newline (to start a new line) or a tab (to indent). Escape
sequences are secret codes that start with a backslash (\). The
backslash tells Pebble: "the next character is special — don't treat
it as a normal letter."
Here are all the escape sequences Pebble supports:
| Escape | What it produces | Example output |
|---|---|---|
\n |
Newline (start a new line) | "a\nb" → two lines |
\t |
Tab (horizontal indent) | "a\tb" → a b |
\\ |
A literal backslash | "a\\b" → a\b |
\" |
A literal double quote | "say \"hi\"" → say "hi" |
\{ |
A literal brace (no interpolation) | "\{x}" → {x} |
\0 |
Null character | (rarely used) |
The \{ escape is handy when you want a { in your string without
triggering string interpolation. See the
interpolation docs for more on that.
If you use an unknown escape like \z, Pebble will give you an error
right away — this catches typos early:
Escapes work inside interpolated strings too:
Changing Case
upper()
Convert every letter to UPPERCASE:
lower()
Convert every letter to lowercase:
You can chain methods — the result of one feeds into the next:
Trimming Whitespace
strip()
Remove spaces (and tabs, newlines) from both ends:
The characters inside the string are untouched — only the edges get trimmed.
Splitting and Joining
split()
Break a string into a list of pieces. With no argument it splits on whitespace:
Pass a separator to split on something specific:
join()
The opposite of split — glue a list of strings together using the target
string as the separator:
Split and join are inverses — splitting then joining with the same separator gives you the original string back:
Searching
contains()
Check if a substring exists anywhere inside the string:
print("hello world".contains("world")) # prints: true
print("hello world".contains("xyz")) # prints: false
starts_with()
Check if the string begins with a prefix:
ends_with()
Check if the string ends with a suffix:
find()
Return the index where a substring first appears, or -1 if it's not found:
count()
Count how many times a substring appears (non-overlapping):
Replacing
replace()
Replace every occurrence of one substring with another:
If the old substring isn't found, the original string is returned unchanged.
Repeating
repeat()
Repeat the string a given number of times:
Passing 0 gives an empty string. Negative numbers are an error.
Using Methods with Other Features
In string interpolation
In conditions
In loops
Quick Reference
| Method | Args | Returns | Description |
|---|---|---|---|
upper() |
0 | str | Uppercase version |
lower() |
0 | str | Lowercase version |
strip() |
0 | str | Trimmed version |
split() |
0 or 1 | list | Split into parts |
replace(old,new) |
2 | str | Replace all occurrences |
contains(sub) |
1 | bool | Is sub inside? |
starts_with(pre) |
1 | bool | Starts with pre? |
ends_with(suf) |
1 | bool | Ends with suf? |
find(sub) |
1 | int | Index of sub, or -1 |
count(sub) |
1 | int | Occurrences of sub |
join(list) |
1 | str | Glue list items with this string |
repeat(n) |
1 | str | Repeat n times |
How It Works Under the Hood
When you write s.upper(), here's the journey:
- Lexer — sees the
.and produces aDOTtoken between the identifier and the method name. - Parser — recognises the dot-method-parentheses pattern and builds a
MethodCallAST node (target =s, method ="upper", args =[]). - Analyzer — checks that
"upper"is a known method and that you passed the right number of arguments. - Compiler — pushes the target onto the stack, pads any missing optional
arguments with a sentinel value, then emits
CALL_METHOD "upper". - VM — pops the arguments and target, looks at the target's type to pick the right handler, calls it, and pushes the result back.
Think of CALL_METHOD like a waiter at a restaurant: you hand over your
order (the method name) and your plate (the target), and the waiter delivers
the result back to your table (the stack).