Perl Integration
Bidirectional integration between Strada and Perl 5.
Strada provides two-way integration with Perl:
- Strada calling Perl - Embed a Perl interpreter in Strada programs
- Perl calling Strada - Load Strada shared libraries from Perl
Strada Calling Perl
The perl5 module allows Strada programs to embed and interact with a Perl 5 interpreter. This gives you access to the entire CPAN ecosystem from Strada.
Basic Usage
use lib "lib";
use perl5;
func main() int {
# Initialize Perl (required first)
perl5::init();
# Evaluate expressions
my str $result = perl5::eval("2 ** 10");
say("2^10 = " . $result); # 1024
# Define and call subroutines
perl5::run("sub double { return $_[0] * 2; }");
my str $doubled = perl5::call("double", "21");
say("21 doubled = " . $doubled); # 42
# Use CPAN modules
if (perl5::use_module("List::Util") == 1) {
perl5::run("@nums = (1, 5, 3, 9, 2);");
my str $max = perl5::eval("List::Util::max(@nums)");
say("Max: " . $max); # 9
}
# Cleanup
perl5::shutdown();
return 0;
}
Compilation
You need to link against libperl when compiling:
# Compile with Perl embedding flags
./strada myapp.strada $(perl -MExtUtils::Embed -e ccopts -e ldopts)
API Reference
| Function | Description |
|---|---|
perl5::init() |
Initialize Perl interpreter. Returns 1 on success, 0 on failure. |
perl5::shutdown() |
Shutdown the Perl interpreter and free resources. |
perl5::is_init() |
Check if Perl is initialized. Returns 1 if yes, 0 if no. |
perl5::eval($code) |
Evaluate Perl code and return the result as a string. |
perl5::run($code) |
Execute Perl code without returning a value. |
perl5::call($sub, $arg) |
Call a Perl subroutine with a single string argument. |
perl5::call_noargs($sub) |
Call a Perl subroutine with no arguments. |
perl5::call_list($sub, $sep) |
Call a sub that returns a list, join with separator. |
perl5::use_module($mod) |
Load a Perl module (like use Module;). Returns 1 on success. |
perl5::require_module($mod) |
Require a Perl module. Returns 1 on success. |
perl5::set_var($name, $val) |
Set a Perl scalar variable. |
perl5::get_var($name) |
Get the value of a Perl scalar variable. |
perl5::add_inc($path) |
Add a path to Perl's @INC. |
perl5::get_error() |
Get the last Perl error ($@). |
Working with Variables
# Set and get Perl variables
perl5::set_var("$name", "Alice");
perl5::set_var("$age", "30");
my str $name = perl5::get_var("$name");
say("Name: " . $name); # Alice
# Work with arrays and hashes in Perl
perl5::run("@colors = qw(red green blue);");
perl5::run("%person = (name => 'Bob', age => 25);");
my str $count = perl5::eval("scalar(@colors)");
my str $person_name = perl5::eval("$person{name}");
Using CPAN Modules
# HTTP requests with LWP
if (perl5::use_module("LWP::Simple") == 1) {
my str $html = perl5::eval("get('http://example.com')");
say("Got " . length($html) . " bytes");
}
# JSON parsing
if (perl5::use_module("JSON") == 1) {
perl5::set_var("$json_str", "{\"name\":\"test\"}");
perl5::run("$data = decode_json($json_str);");
my str $name = perl5::eval("$data->{name}");
}
# Database access with DBI
if (perl5::use_module("DBI") == 1) {
perl5::run("$dbh = DBI->connect('dbi:SQLite:test.db');");
perl5::run("$sth = $dbh->prepare('SELECT * FROM users');");
perl5::run("$sth->execute();");
# ... process results
}
XS Module Support
XS-based Perl modules (compiled modules like POSIX, JSON::XS, DBI) require the Perl library to be preloaded:
# Find your libperl path
perl -MConfig -e 'print $Config{archlib}'
# Run with LD_PRELOAD
LD_PRELOAD=/lib/x86_64-linux-gnu/libperl.so.5.38 ./myapp
Pure Perl modules work without this workaround.
Error Handling
# Check for errors after eval
my str $result = perl5::eval("some_code()");
my str $error = perl5::get_error();
if (length($error) > 0) {
say("Perl error: " . $error);
} else {
say("Result: " . $result);
}
Perl Calling Strada
The Strada Perl module allows Perl programs to load and call functions from compiled Strada shared libraries. This lets you write performance-critical code in Strada and use it from Perl.
Setup
# Build the Perl XS module
cd perl/Strada
perl Makefile.PL
make
make test
make install # optional
Creating a Strada Library
First, write your Strada code as a library:
# mylib.strada
package mylib;
func add(int $a, int $b) int {
return $a + $b;
}
func greet(str $name) str {
return "Hello, " . $name . "!";
}
func sum_list(scalar $items) int {
my int $sum = 0;
foreach my int $x ($items) {
$sum = $sum + $x;
}
return $sum;
}
Compile it as a shared library:
./strada --shared mylib.strada
# Creates mylib.so
Using from Perl
#!/usr/bin/perl
use Strada;
# Load the library
my $lib = Strada::Library->new('./mylib.so');
# Call functions using namespace syntax
my $sum = $lib->call('mylib::add', 10, 20);
print "10 + 20 = $sum\n"; # 30
my $greeting = $lib->call('mylib::greet', 'Perl');
print "$greeting\n"; # Hello, Perl!
# Pass arrays
my $total = $lib->call('mylib::sum_list', [1, 2, 3, 4, 5]);
print "Sum: $total\n"; # 15
# Unload when done
$lib->unload();
Function Naming Convention
Strada functions are exported as package_function (underscore-separated). The Perl module accepts both styles:
| Strada Declaration | C Name | Perl Call (both work) |
|---|---|---|
package foo; func bar() |
foo_bar |
'foo_bar' or 'foo::bar' |
package utils; func format() |
utils_format |
'utils_format' or 'utils::format' |
package MyLib; func process() |
MyLib_process |
'MyLib_process' or 'MyLib::process' |
:: to _, so you can use familiar Strada/Perl syntax like $lib->call('mylib::add', 1, 2).
Type Conversion
Types are automatically converted between Strada and Perl:
| Strada Type | Perl Type |
|---|---|
int |
Integer (IV) |
num |
Float (NV) |
str |
String (PV) |
array |
Array reference |
hash |
Hash reference |
undef |
undef |
Use Cases
Access CPAN from Strada
Use any of the thousands of CPAN modules from your Strada programs:
perl5::init();
# Parse YAML
perl5::use_module("YAML");
my str $yaml = perl5::eval("YAML::Dump({name => 'test'})");
# Send email
perl5::use_module("Email::Simple");
perl5::use_module("Email::Sender::Simple");
# Date handling
perl5::use_module("DateTime");
my str $now = perl5::eval("DateTime->now->iso8601");
perl5::shutdown();
High-Performance Code from Perl
Write performance-critical code in compiled Strada, call from Perl:
#!/usr/bin/perl
use Strada;
my $lib = Strada::Library->new('./libcompute.so');
# Strada handles the heavy lifting
for my $data (@large_dataset) {
my $result = $lib->call('compute::process', $data);
push @results, $result;
}
$lib->unload();
Mixed Language Projects
Combine the strengths of both languages:
- Strada - Type-safe, compiled performance, native binaries
- Perl - Rapid prototyping, text processing, CPAN ecosystem
Directory Structure
lib/
perl5.strada # Strada module for calling Perl
perl/
Strada/
Strada.xs # XS implementation
Strada.pm # Perl module
Makefile.PL # Build configuration
t/
01_basic.t # Test suite
See Also
- C Interoperability - Working with C code directly
- Libraries Guide - Creating and using Strada libraries
examples/test_perl5.strada- Complete example program