Built-in Functions
Complete reference for all built-in functions.
Output Functions
| Function | Description |
|---|---|
say($value) | Print value with newline |
print($value) | Print value without newline |
warn($msg) | Print warning to stderr |
die($msg) | Print error and exit |
String Functions
| Function | Description |
|---|---|
length($str) | Length in Unicode codepoints (use core::byte_length for raw bytes) |
strlen($str) | Alias for length |
substr($str, $start, $len) | Extract substring (offsets are codepoint positions, UTF-8 safe) |
index($str, $substr) | Find first occurrence (codepoint position), -1 if not found |
rindex($str, $substr) | Find last occurrence (codepoint position) |
uc($str) | Convert to uppercase |
lc($str) | Convert to lowercase |
ucfirst($str) | Uppercase first character |
lcfirst($str) | Lowercase first character |
trim($str) | Remove leading/trailing whitespace |
split($sep, $str) | Split string into array |
join($sep, @arr) | Join array into string |
chr($code) | Character from ASCII code |
ord($char) | ASCII code from character |
sprintf($fmt, ...) | Formatted string (like C sprintf) |
stringify($val) | Convert value to string |
String Repetition Operator (x)
The x operator repeats a string a given number of times. It has the same precedence as *, /, and %.
my str $dashes = "-" x 40;
say($dashes); # "----------------------------------------"
my str $ab = "ab" x 3;
say($ab); # "ababab"
# Useful for formatting
say("=" x 60);
say(" Report Title");
say("=" x 60);
Transliteration (tr///, y///)
The tr/// operator (alias y///) performs character-by-character transliteration. Unlike s///, it does not use regex — it maps individual characters from one set to another.
| Syntax | Description |
|---|---|
$str =~ tr/abc/xyz/; | Replace a with x, b with y, c with z (modifies in place) |
$str =~ y/abc/xyz/; | Same as tr/// (Perl alias) |
my str $new = ($str =~ tr/abc/xyz/r); | Return new string instead of modifying (with /r flag) |
Flags
| Flag | Description |
|---|---|
c | Complement — transliterate characters NOT in the search list |
d | Delete — delete characters with no replacement |
s | Squeeze — collapse duplicate replaced characters into one |
r | Return — return new string, do not modify original |
my str $text = "Hello World";
# ROT13
$text =~ tr/A-Za-z/N-ZA-Mn-za-m/;
say($text); # "Uryyb Jbeyq"
# Lowercase to uppercase
my str $upper = "hello";
$upper =~ tr/a-z/A-Z/;
say($upper); # "HELLO"
# Delete digits
my str $nodigits = "abc123def456";
$nodigits =~ tr/0-9//d;
say($nodigits); # "abcdef"
# Squeeze repeated spaces
my str $spaced = "hello world";
$spaced =~ tr/ / /s;
say($spaced); # "hello world"
# Return modified copy (original unchanged)
my str $original = "hello";
my str $copy = ($original =~ tr/a-z/A-Z/r);
say($original); # "hello" (unchanged)
say($copy); # "HELLO"
Examples
my str $s = " Hello World ";
say(strlen($s)); # 15
say(trim($s)); # "Hello World"
say(substr($s, 2, 5)); # "Hello"
say(uc($s)); # " HELLO WORLD "
say(index($s, "World")); # 8
my array @parts = split(" ", trim($s));
say(join("-", @parts)); # "Hello-World"
Array Functions
| Function | Description |
|---|---|
len(@arr) | Return array length |
scalar(@arr) | Return array length (alias for len) |
push(@arr, $val) | Add element to end |
pop(@arr) | Remove and return last element |
shift(@arr) | Remove and return first element |
unshift(@arr, $val) | Add element to beginning |
reverse(@arr) | Reverse array elements in place |
sort(@arr) | Return sorted array |
splice(@arr, $off, $len) | Remove elements, return removed |
splice(@arr, $off, $len, @repl) | Remove and replace with @repl, return removed |
splice() in Detail
The splice() function removes elements from an array and optionally replaces them. It returns an array of the removed elements.
my array @data = (10, 20, 30, 40, 50);
# Remove 2 elements starting at index 1
my array @removed = splice(@data, 1, 2);
# @removed = (20, 30), @data = (10, 40, 50)
# Replace 1 element at index 1 with two new elements
my array @arr = ("a", "b", "c", "d");
my array @repl = ("X", "Y");
splice(@arr, 1, 1, @repl);
# @arr = ("a", "X", "Y", "c", "d")
# Insert without removing (len = 0)
my array @list = (1, 2, 5);
my array @insert = (3, 4);
splice(@list, 2, 0, @insert);
# @list = (1, 2, 3, 4, 5)
Array Memory Management
| Function | Description |
|---|---|
reserve(@arr, $n) | Ensure capacity for at least $n elements |
Pre-allocating Arrays
For performance, pre-allocate arrays when you know the approximate size:
my array @data[1000]; # Pre-allocate for 1000 elements
for (my int $i = 0; $i < 1000; $i++) {
push(@data, $i); # No reallocation needed
}
Array Transformations (map, grep, sort)
Strada supports Perl-style block expressions for powerful array transformations. The special variable $_ contains the current element.
| Expression | Description |
|---|---|
map { expr } @arr | Transform each element |
grep { cond } @arr | Filter elements where condition is true |
sort { $a <=> $b } @arr | Sort with custom comparison ($a, $b) |
sort @arr | Sort alphabetically (default) |
Map Examples
my array @nums = (1, 2, 3, 4, 5);
# Transform each element (double)
my array @doubled = map { $_ * 2 } @nums;
# Result: (2, 4, 6, 8, 10)
# Transform to strings
my array @strings = map { "Value: " . $_ } @nums;
Map with Fat Arrow (Creating Hashes)
The classic Perl idiom for building lookup hashes works in Strada:
my array @fruits = ("apple", "banana", "cherry");
# Create a lookup hash - the Perl way!
my hash %lookup = map { $_ => 1 } @fruits;
# %lookup is now {"apple" => 1, "banana" => 1, "cherry" => 1}
# Fast membership testing
if (exists($lookup{"apple"})) {
say("Found apple!");
}
The fat arrow $_ => value creates a key-value pair. When assigned to a hash variable, these pairs become hash entries.
Grep Examples
my array @nums = (1, 2, 3, 4, 5, 6);
# Keep only even numbers
my array @evens = grep { $_ % 2 == 0 } @nums;
# Result: (2, 4, 6)
# Keep values greater than 3
my array @big = grep { $_ > 3 } @nums;
# Result: (4, 5, 6)
Sort Examples
my array @nums = (5, 2, 8, 1, 9);
# Sort ascending (numeric) - use spaceship operator
my array @asc = sort { $a <=> $b } @nums;
# Result: (1, 2, 5, 8, 9)
# Sort descending
my array @desc = sort { $b <=> $a } @nums;
# Result: (9, 8, 5, 2, 1)
# Default sort (alphabetical)
my array @alpha = sort @names;
Chaining Operations
my array @data = (5, 2, 8, 1, 9, 3, 7);
# Filter, transform, and sort in one pipeline
my array @result = sort { $a <=> $b } map { $_ * 10 } grep { $_ > 3 } @data;
# Result: (50, 70, 80, 90)
Hash Functions
| Function | Description |
|---|---|
keys(%hash) | Return array of keys |
values(%hash) | Return array of values |
exists(%hash, $key) | Check if key exists (returns 1/0) |
delete(%hash, $key) | Remove key-value pair |
each(%hash) | Return next [key, value] pair; empty array when done |
core::hash_default_capacity($n) | Set default capacity for new hashes |
each() Iterator
The each() function returns the next key-value pair from a hash as a two-element array [key, value]. When all pairs have been returned, it returns an empty array. The iterator resets when all entries have been traversed.
my hash %config = ();
$config{"host"} = "localhost";
$config{"port"} = 8080;
$config{"debug"} = 1;
# Iterate with each()
my array @pair = each(%config);
while (scalar(@pair) > 0) {
say($pair[0] . " = " . $pair[1]);
@pair = each(%config);
}
# Output (order may vary):
# host = localhost
# port = 8080
# debug = 1
Pre-allocating Hashes
Pre-allocate hashes when you know the approximate size:
my hash %cache[500]; # Pre-allocate for ~500 entries
# Or set default for all new hashes:
core::hash_default_capacity(1000);
Hashes automatically resize for O(1) average lookup time.
Type Functions
| Function | Description |
|---|---|
int($val) | Convert to integer |
num($val) | Convert to number |
defined($val) | Check if value is defined |
ref($val) | Return reference type or empty string |
typeof($val) | Return type as string |
bless(\%h, $class) | Associate hash ref with class |
core::weaken($ref) | Make $ref a weak reference (break circular refs) |
core::isweak($ref) | Returns 1 if $ref is weak, 0 otherwise |
File I/O Functions
| Function | Description |
|---|---|
slurp($path) | Read entire file as string |
spew($path, $data) | Write string to file |
core::open($path, $mode) | Open file, return filehandle (modes: "r"/"<", "w"/">", "a"/">>") |
core::open(\$var, $mode) | Open in-memory handle (ref-style, writeback on close) |
core::open_str($content, $mode) | Open in-memory handle from string |
core::str_from_fh($fh) | Extract string from memstream |
core::readline($fh) | Read line from filehandle |
core::read($fd, $len) | Read bytes from fd |
core::fwrite($fd, $data) | Write bytes to fd |
core::close($fd) | Close file descriptor |
core::seek($fd, $pos, $whence) | Seek in file |
core::tell($fd) | Get current position |
core::eof($fd) | Check if at end of file |
core::flush($fd) | Flush file buffer |
select($fh) | Set default filehandle for print/say |
select() — Default Filehandle
The select() function sets the default output filehandle. After calling select($fh), all print() and say() calls without an explicit filehandle will write to $fh instead of stdout.
my scalar $fh = core::open("output.log", "w");
# Redirect print/say to the file
select($fh);
say("This goes to output.log");
print("So does this");
# Restore stdout (pass undef or no argument)
select(undef);
say("Back to stdout");
core::close($fh);
Diamond Operator <$fh>
The diamond operator reads lines from a filehandle or socket. Context determines behavior:
| Syntax | Context | Description |
|---|---|---|
my str $line = <$fh> | Scalar | Read one line (strips newline) |
my array @lines = <$fh> | Array | Read ALL lines into array |
@lines = <$fh> | Array | Read ALL lines (assignment) |
<$sock> | Any | Works with sockets too (strips \r\n) |
Filehandle I/O
Say and print work with filehandles as the first argument:
| Syntax | Description |
|---|---|
say($fh, $text) | Write text with newline to filehandle/socket |
print($fh, $text) | Write text without newline to filehandle/socket |
In-Memory I/O
Read from and write to strings using standard file handle operations. All I/O functions work transparently with in-memory handles.
# Read from a string
my scalar $fh = core::open_str("line1\nline2\n", "r");
my str $line = <$fh>; # "line1"
# Write to a string buffer
my scalar $wfh = core::open_str("", "w");
say($wfh, "hello");
my str $result = core::str_from_fh($wfh); # "hello\n"
# Reference-style (variable updated on close)
my str $output = "";
my scalar $wfh2 = core::open(\$output, "w");
say($wfh2, "data");
core::close($wfh2); # $output = "data\n"
Math Functions (math::)
| Function | Description |
|---|---|
math::abs($n) | Absolute value |
math::floor($n) | Round down |
math::ceil($n) | Round up |
math::round($n) | Round to nearest |
math::sqrt($n) | Square root |
math::pow($base, $exp) | Power |
math::sin($n) | Sine |
math::cos($n) | Cosine |
math::tan($n) | Tangent |
math::log($n) | Natural logarithm |
math::log10($n) | Base-10 logarithm |
math::exp($n) | e^n |
math::rand() | Random number 0-1 |
math::srand($seed) | Seed random generator |
System Functions (core::)
Process Control
| Function | Description |
|---|---|
core::exit($code) | Exit with status code |
core::fork() | Fork process |
core::exec($cmd, @args) | Execute command |
core::system($cmd) | Run shell command |
core::wait() | Wait for child process |
core::waitpid($pid) | Wait for specific process |
core::getpid() | Get process ID |
core::getppid() | Get parent process ID |
core::kill($pid, $sig) | Send signal to process |
Environment
| Function | Description |
|---|---|
core::getenv($name) | Get environment variable |
core::setenv($name, $val) | Set environment variable |
core::getcwd() | Get current directory |
core::chdir($path) | Change directory |
File System
| Function | Description |
|---|---|
core::stat($path) | Get file info |
core::mkdir($path) | Create directory |
core::rmdir($path) | Remove directory |
core::unlink($path) | Delete file |
core::rename($old, $new) | Rename file |
core::readdir($path) | List directory |
core::is_dir($path) | Check if directory |
core::is_file($path) | Check if regular file |
core::realpath($path) | Get absolute path |
core::dirname($path) | Get directory part |
core::basename($path) | Get filename part |
core::glob($pattern) | Glob pattern matching |
-e $path | File test: exists (file or directory) |
-f $path | File test: is a regular file |
-d $path | File test: is a directory |
Time
| Function | Description |
|---|---|
core::time() | Unix timestamp |
core::localtime($ts) | Convert to local time hash |
core::gmtime($ts) | Convert to GMT hash |
core::sleep($secs) | Sleep for seconds |
core::usleep($usecs) | Sleep for microseconds |
Debugging
| Function | Description |
|---|---|
core::stack_trace() | Get current call stack as string |
core::caller() | Returns hash with function, file, line of calling frame |
core::caller($level) | Same, but $level frames up (0 = immediate, 1 = grandparent) |
core::full_profile_start($file) | Start line-level profiling, writing output to $file |
core::full_profile_stop() | Stop line-level profiling and flush data to disk |
Call Context (Dynamic Return Type)
| Function | Description |
|---|---|
core::wantarray() | Returns 1 if called in array context |
core::wantscalar() | Returns 1 if called in scalar context (default) |
core::wanthash() | Returns 1 if called in hash context |
Networking
| Function | Description |
|---|---|
core::socket_server($port) | Create TCP server |
core::socket_accept($fd) | Accept connection |
core::socket_connect($host, $port) | Connect to server |
core::gethostbyname($host) | Resolve hostname |
core::gethostbyname_all($host) | Resolve hostname (all addresses) |
core::gethostname() | Get local hostname |
core::getaddrinfo($host, $port) | Advanced address resolution |
SSL/TLS (ssl::)
Secure socket connections via OpenSSL. Build with: cd lib/ssl && make
| Function | Description |
|---|---|
ssl::connect($host, $port) | Connect to TLS server |
ssl::read($conn, $len) | Read from TLS connection |
ssl::write($conn, $data) | Write to TLS connection |
ssl::close($conn) | Close TLS connection |
ssl::http_get($host, $port, $path) | Simple HTTPS GET request |
SSL Example
my int $conn = ssl::connect("example.com", 443);
ssl::write($conn, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
my str $response = ssl::read($conn, 4096);
ssl::close($conn);
# Or use the convenience function:
my str $page = ssl::http_get("example.com", 443, "/");
UTF-8 Introspection (utf8::)
Strada strings carry an internal UTF-8 flag mirroring Perl's
SVf_UTF8. When the flag is set, the character built-ins
(length, substr, index, rindex,
reverse, split, sprintf widths, regex) count
Unicode codepoints; when clear, the string is raw bytes. Pure-ASCII strings are
character-oriented implicitly. chr(N) for N in 0–127 emits one
ASCII byte; for N ≥ 128 it UTF-8-encodes the codepoint and sets the flag
(matching use utf8). The byte-level core::byte_* family is
available when you need raw byte access for binary protocols.
The flag is set by chr(N>127), the utf8::nfc/nfd/nfkc/nfkd
normalizers, and non-ASCII literals in a use utf8 source, and propagates
contagiously through concatenation, join, sprintf, and
s///. The utf8::* functions below are validation/no-op
helpers — they report on the flag rather than transcoding bytes.
| Function | Description |
|---|---|
utf8::is_utf8($str) | Returns 1 if string is valid UTF-8, 0 otherwise |
utf8::valid($str) | Alias for is_utf8() |
utf8::encode($str) | No-op (strings are already bytes), returns the string |
utf8::decode($str) | Validates UTF-8; returns 1 if valid, 0 if not |
utf8::upgrade($str) | No-op (strings are already UTF-8), returns the string |
utf8::downgrade($str) | Returns string if ASCII-only, dies on non-ASCII |
utf8::downgrade($str, 1) | With fail_ok=1, returns undef instead of dying |
utf8::unicode_to_native($cp) | Identity mapping on modern systems |
utf8::nfc($str) | UAX#15 canonical composition (NFC), Unicode 15.0.0 |
utf8::nfd($str) | Canonical decomposition (NFD) |
utf8::nfkc($str) | Compatibility composition (NFKC) |
utf8::nfkd($str) | Compatibility decomposition (NFKD) |
utf8::normalize($form, $str) | Generic: $form = "NFC"/"NFD"/"NFKC"/"NFKD" |
UTF-8 Example
my str $text = "Hello";
say(utf8::is_utf8($text)); # 1 (ASCII is valid UTF-8)
say(utf8::downgrade($text)); # "Hello" (ASCII-only, succeeds)
# Safe downgrade with fail_ok
my scalar $result = utf8::downgrade($text, 1);
if (!defined($result)) {
say("Contains non-ASCII");
}
Signals
| Function | Description |
|---|---|
core::signal($sig, \&handler) | Set signal handler |
core::signal($sig, "IGNORE") | Ignore signal |
core::signal($sig, "DEFAULT") | Reset to default |
Dynamic Loading (FFI)
| Function | Description |
|---|---|
core::dl_open($lib) | Load shared library |
core::dl_sym($handle, $name) | Get symbol address |
core::dl_call_sv($fn, @args) | Call Strada function (returns StradaValue) |
core::dl_call_int_sv($fn, @args) | Call Strada function (returns int) |
core::dl_call_str_sv($fn, @args) | Call Strada function (returns str) |
core::dl_call_void_sv($fn, @args) | Call Strada function (void return) |
core::dl_call_version($fn) | Get library version string |
core::dl_close($handle) | Unload library |
FFI Example
# Load a Strada shared library
my int $lib = core::dl_open("./mylib.so");
my int $fn = core::dl_sym($lib, "my_function");
my scalar $result = core::dl_call_sv($fn, [$arg1, $arg2]);
Library Imports
The plain use statement auto-detects a precompiled sibling artifact (.o preferred over .so) next to the .strada source, with an mtime freshness check. Falls back to source inlining when the artifact is stale or missing.
use lib "lib";
use JSON; # picks up lib/JSON.o (or .so) if present
# Explicit forms — useful when no .strada is alongside the artifact:
import_lib "JSON.so"; # Runtime loading (dlopen)
import_object "Utils.o"; # Static linking
import_archive "DataLib.a"; # Static linking with bundled runtime
# Functions are available with namespace syntax:
my str $json = JSON::encode(\%data);
Library Compilation
Compile Strada modules as reusable artifacts:
./strada -M lib/JSON.strada # module-only JSON.o (recommended)
./strada -M lib/ # recursive: every .strada → sibling .o
./strada --object-full mylib.strada -o mylib.o # bundle deps (legacy)
./strada --shared mylib.strada -o mylib.so # shared object (.so)
./strada --static-lib mylib.strada -o mylib.a # static archive (includes runtime)
Declaring extern-C Link Deps (link_lib)
A module that wraps a C library advertises its -l deps so consumers don't have to:
package DBI;
link_lib "sqlite3";
link_lib "mysqlclient";
# ... when something does `use DBI;`, the strada driver adds -lsqlite3 -lmysqlclient automatically.
C Interop (__C__ Blocks)
Embed raw C code directly in Strada programs using __C__ blocks:
Top-Level Blocks
For includes, globals, and C helper functions:
__C__ {
#include <math.h>
#include <openssl/ssl.h>
static SSL_CTX *g_ctx = NULL;
static int helper(int a, int b) {
return a + b;
}
}
Statement-Level Blocks
Inline C code inside functions with access to Strada variables:
func my_sqrt(num $x) num {
__C__ {
double val = strada_to_num(x);
return strada_new_num(sqrt(val));
}
}
Key C Functions
| Function | Description |
|---|---|
strada_to_int(sv) | Extract int64_t from StradaValue* |
strada_to_num(sv) | Extract double from StradaValue* |
strada_to_str(sv) | Extract string (caller must free!) |
strada_new_int(i) | Create StradaValue* from int64_t |
strada_new_num(n) | Create StradaValue* from double |
strada_new_str(s) | Create StradaValue* from string |
&strada_undef | Return undef value |
Opaque Handle Pattern
Store C pointers in Strada int variables (64-bit):
func open_connection(str $host) int {
__C__ {
char *h = strada_to_str(host);
SSL *conn = connect_ssl(h);
free(h);
// Store pointer as int
return strada_new_int((int64_t)(intptr_t)conn);
}
}
func close_connection(int $handle) void {
__C__ {
// Retrieve pointer from int
SSL *conn = (SSL*)(intptr_t)strada_to_int(handle);
SSL_free(conn);
return &strada_undef;
}
}
JSON Functions
| Function | Description |
|---|---|
JSON::encode($val) | Convert to JSON string |
JSON::decode($str) | Parse JSON string |
Package Syntax
| Syntax | Description |
|---|---|
__PACKAGE__ | Current package name (runtime) |
::func() | Call func in current package (compile-time) |
.::func() | Alternate syntax for above |
__PACKAGE__::func() | Explicit form of above |
use overload "+" => "method", ...; | Operator overloading for current package |
Example
package Calculator;
func add(int $a, int $b) int { return $a + $b; }
func compute(int $x, int $y) int {
return ::add($x, $y); # Calls Calculator_add
}
Moose-Style OOP Keywords
Strada provides a declarative OOP system inspired by Perl's Moose. See the OOP page for full details and examples.
| Syntax | Description |
|---|---|
has ro type $name; | Declare read-only attribute with getter |
has rw type $name; | Declare read-write attribute with getter and setter |
has ro type $name (required); | Required attribute (must be passed to constructor) |
has rw type $name = default; | Attribute with default value |
extends Parent; | Inherit from one or more parent classes |
extends Parent1, Parent2; | Multiple inheritance |
with Role; | Compose a role (mixin) into the class |
before "method" func($self) void { } | Run code before a method call |
after "method" func($self) void { } | Run code after a method call |
around "method" func($self) void { } | Wrap a method call entirely |
When a package uses has declarations, the compiler automatically generates a new() constructor that accepts named arguments as alternating key-value pairs. If you define your own new(), the auto-generated one is skipped.
my scalar $obj = MyClass::new("name", "value", "age", 30);
core:: Namespace Alias
The core:: namespace is the preferred way to call system functions. It is an alias for the older sys:: namespace. The compiler normalizes core:: to sys:: at compile time, so there is zero overhead. Both namespaces work interchangeably.
| core:: Call (preferred) | Legacy sys:: Call |
|---|---|
core::exit(0) | sys::exit(0) |
core::open($path, "r") | sys::open($path, "r") |
core::time() | sys::time() |
core::getenv("HOME") | sys::getenv("HOME") |
core::fork() | sys::fork() |
Use whichever namespace feels more natural. core:: is recommended for new code as it reads more clearly as "core language functionality."
# These are equivalent:
my int $pid = core::fork();
my int $pid = sys::fork();
my str $home = core::getenv("HOME");
my str $home = sys::getenv("HOME");
my int $now = core::time();
my int $now = sys::time();
Miscellaneous
| Function | Description |
|---|---|
dump($val) | Debug print value structure |
caller() | Get caller information |
eval($code) | Evaluate Strada code string |
$obj->isa($class) | Check if object is instance of class |
$obj->can($method) | Check if object has method |
$obj->$method() | Dynamic method dispatch (name from variable) |
local($var) | Dynamic scoping for our variables |
local() — Dynamic Scoping
The local() function provides dynamic scoping for our (package-global) variables. It saves the current value and automatically restores it when the enclosing scope exits. This is useful for temporarily overriding globals without affecting the rest of the program.
our int $verbose = 0;
func debug_section() void {
local($verbose) = 1; # Temporarily set to 1
do_work(); # $verbose is 1 here
# $verbose automatically restored to 0 on scope exit
}
func do_work() void {
if ($verbose) {
say("Doing work..."); # Prints when called from debug_section
}
}
func main() int {
do_work(); # $verbose is 0, nothing printed
debug_section(); # $verbose is temporarily 1 inside
do_work(); # $verbose is 0 again
return 0;
}
local() provides dynamic scoping — the localized value is visible in the current function and all functions called from it. my provides lexical scoping — the variable is only visible in the current block. local() only works with our variables (package globals).
tie/untie/tied — Tied Hashes
The tie mechanism binds a hash variable to a class, allowing custom behavior for hash operations. When a hash is tied, all accesses (read, write, delete, exists, iteration) are dispatched to methods in the tied class.
| Function | Description |
|---|---|
tie(%hash, "ClassName", @args) | Bind hash to class; calls TIEHASH(@args) |
untie(%hash) | Unbind hash from class |
tied(%hash) | Return the tied object, or undef if not tied |
TIEHASH Methods
The tied class must implement these methods:
| Method | Description |
|---|---|
TIEHASH(@args) | Constructor — called by tie(), returns the tied object |
FETCH($self, $key) | Called when reading: $hash{$key} |
STORE($self, $key, $val) | Called when writing: $hash{$key} = $val |
DELETE($self, $key) | Called for: delete($hash{$key}) |
EXISTS($self, $key) | Called for: exists($hash{$key}) |
FIRSTKEY($self) | Called to start iteration (keys, each) |
NEXTKEY($self, $lastkey) | Called for subsequent keys during iteration |
CLEAR($self) | Called when hash is cleared |
Example: Case-Insensitive Hash
package CIHash;
func TIEHASH() scalar {
my hash %self = ();
$self{"data"} = {};
return bless(\%self, "CIHash");
}
func FETCH(scalar $self, str $key) scalar {
return $self->{"data"}->{lc($key)};
}
func STORE(scalar $self, str $key, scalar $val) void {
$self->{"data"}->{lc($key)} = $val;
}
package main;
func main() int {
my hash %h = ();
tie(%h, "CIHash");
$h{"Name"} = "Alice"; # Calls CIHash::STORE
say($h{"name"}); # Calls CIHash::FETCH -> "Alice"
say($h{"NAME"}); # "Alice" (case insensitive)
untie(%h); # Unbind from class
return 0;
}
When a hash is not tied, hash operations compile to the same code as before — no dispatch checks, no extra branches. The tied mechanism only adds overhead to hashes that are actually tied.
Compiler Flags
The Strada compiler (stradac) and wrapper (strada) support these flags:
| Flag | Description |
|---|---|
-r, --run | Compile and run immediately |
-c, --keep-c | Keep generated .c file |
-g, --debug | Include debug symbols |
-p, --profile | Enable function profiling (report to stderr at exit) |
--full-profile | Line-level profiling (writes strada-prof.out; implies -g) |
-w, --warnings | Show compiler warnings |
-t, --timing | Show compilation phase timing |
--shared | Compile as shared library (.so) |
-L <path> | Add library search path (high priority) |
-LL <path> | Add library search path (low priority) |
Examples
# Compile and run
./strada -r program.strada
# Compile with debugging
./strada -g program.strada
# Compile with function profiling
./strada -p program.strada
./program # Prints profiling report on exit
# Compile with line-level profiling
./strada --full-profile program.strada
./program # Writes strada-prof.out
strada-proftext strada-prof.out # Text report
strada-profhtml strada-prof.out profhtml/ # HTML report
# Check for warnings
./strada -w program.strada
# Create shared library
./strada --shared mylib.strada # Creates mylib.so