SlideShare a Scribd company logo
The Perl API
for the

Mortally Terrified
Mike Friedman
(friedo)

London Perl Workshop
November 30, 2013
Me
Mike Friedman
Mike Friedman
(friedo)
This talk
is the product of a lengthy journey.
This talk
is the product of a lengthy journey.

It's also a work in progress.
I have some limited
experience in integrating
Perl and C with XS, and
would enjoy the opportunity
to expand my skills in this
area.
i R dum.
The Perl API for the Mortally Terrified (beta)
- Learned from this book.
- Learned from this book.
- It’s very good
- Learned from this book.
- It’s very good
- The printing I got was messed up.
- Learned from this book.
- It’s very good
- The printing I got was messed up.
- Like every " was replaced by ©
The Perl API
What’s it good for?
Make things fast:
The Perl API
What’s it good for?
Make things fast:
- Write your slow Perl code in C
The Perl API
What’s it good for?
Make things fast:
- Write your slow Perl code in C
- Keep your fast Perl code in Perl
The Perl API
What’s it good for?
Make Perl more useful:
The Perl API
What’s it good for?
Make Perl more useful:
- Interface with libraries written in C
The Perl API
What’s it good for?
Make Perl more useful:
- Interface with libraries written in C
- Create modules exposing external APIs to Perl
The Perl API
What’s it good for?
Make Perl do...stuff
The Perl API
What’s it good for?
Make Perl do...stuff
- Change opcodes on the fly?
The Perl API
What’s it good for?
Make Perl do...stuff
- Change opcodes on the fly?
- Extend the parser?
The Perl API
What’s it good for?
Make Perl do...stuff
- Change opcodes on the fly?
- Extend the parser?
- Make exceptions work?
The Perl API
What’s it good for?
Make Perl do...stuff
- Change opcodes on the fly?
- Extend the parser?
- Make exceptions work?
- Why not?
The Perl API
What’s it good for?
Make Perl do...stuff
- Change opcodes on the fly?
- Extend the parser?
- Make exceptions work?
- Why not?
A Crash Course in

C
C Crash Course

Basic Types (there are more)
C Crash Course

Basic Types (there are more)
char

foo

= ‘a’;
C Crash Course

Basic Types (there are more)
char
int

foo
bar

= ‘a’;
= 42;
C Crash Course

Basic Types (there are more)
char
int
long

foo
bar
baz

= ‘a’;
= 42;
= 198547;
C Crash Course

Basic Types (there are more)
char
int
long
float

foo
bar
baz
quux

=
=
=
=

‘a’;
42;
198547;
3.14159;
C Crash Course

Basic Types (there are more)
char
int
long
float
double

foo
bar
baz
quux
splat

=
=
=
=
=

‘a’;
42;
198547;
3.14159;
3.14159265358979;
C Crash Course

Pointers
C Crash Course

Pointers
char

*foo;

/* ptr to char

*/
C Crash Course

Pointers
char
int

*foo;
*bar;

/* ptr to char
/* ptr to int

*/
*/
C Crash Course

Pointers
char
int
long

*foo;
*bar;
*baz;

/* ptr to char
/* ptr to int
/* ptr to long

*/
*/
*/
C Crash Course

Pointers
char
int
long
float

*foo;
*bar;
*baz;
*quux;

/*
/*
/*
/*

ptr
ptr
ptr
ptr

to
to
to
to

char
int
long
float

*/
*/
*/
*/
C Crash Course

Pointers
char
int
long
float
double

*foo;
*bar;
*baz;
*quux;
*splat;

/*
/*
/*
/*
/*

ptr
ptr
ptr
ptr
ptr

to
to
to
to
to

char
int
long
float
double

*/
*/
*/
*/
*/
C Crash Course

Pointers
char
int
long
float
double
void

*foo;
*bar;
*baz;
*quux;
*splat;
*fnarf;

/*
/*
/*
/*
/*
/*

ptr
ptr
ptr
ptr
ptr
ptr

to
to
to
to
to
to

char
int
long
float
double
something

*/
*/
*/
*/
*/
*/
C Crash Course

Pointers are integer variables which
hold a memory address.
C Crash Course

C

Perl
C Crash Course

C
int i

Perl
= 42;

my $i

= 42;
C Crash Course

C
int i
= 42;
int *i_ptr = &i;

Perl
my $i
= 42;
my $i_ref = $i;
C Crash Course

C

Perl

int i
= 42;
my $i
= 42;
int *i_ptr = &i;
my $i_ref = $i;
Read unary & as “address-of.”
C Crash Course

C

Perl

int i
= 42;
my $i
= 42;
int *i_ptr = &i;
my $i_ref = $i;
Read unary & as “address-of.”
int j;

my $j;
C Crash Course

C

Perl

int i
= 42;
my $i
= 42;
int *i_ptr = &i;
my $i_ref = $i;
Read unary & as “address-of.”
int j;
j = *i_ptr;

my $j;
$j = $$i_ref;
C Crash Course

C

Perl

int i
= 42;
my $i
= 42;
int *i_ptr = &i;
my $i_ref = $i;
Read unary & as “address-of.”
int j;
j = *i_ptr;

my $j;
$j = $$i_ref;

Read unary * as “dereference.”
C Crash Course

Aggregates
C Crash Course

Aggregates
int

foo[10];

/* array of ints */
C Crash Course

Aggregates
int
float

foo[10];
bar[12];

/* array of ints */
/* array of floats */
C Crash Course

Aggregates
int
float
char

foo[10];
bar[12];
baz[42];

/* array of ints */
/* array of floats */
/* a string! */
C Crash Course

Aggregates
C Crash Course

Aggregates
struct person {
int age;
char *name;
double acct_balance;
};
C Crash Course

Aggregates
struct person {
int age;
char *name;
double acct_balance;
};
age

*name

acct_balance
...
C Crash Course

Aggregates
C Crash Course

Aggregates
union thingy {
long num;
char chars[4];
foo_t *myfoo;
};
C Crash Course

Aggregates
union thingy {
long num;
char chars[4];
foo_t *myfoo;
};
thingy.num
thingy.chars
thingy.myfoo

f3

de

42

9a
C Crash Course

Using structs
C Crash Course

Using structs
struct person the_dude;
the_dude.age = 42;
the_dude.name = “jeffrey lebowski”;
the_dude.acct_balance = 1.79;
C Crash Course

Using structs
struct person the_dude;
the_dude.age = 42;
the_dude.name = “jeffrey lebowski”;
the_dude.acct_balance = 1.79;
00

2a

age

3f

39

d2

90

a4

70

3d

*name

0a

d7

a3

fc

acct_balance
j

e

f

f

r

e

y

...

3f
C Crash Course

Typedefs
typedef struct {
int age;
char *name;
double acct_balance;
} person;
person the_dude;
XS
What is XS?

perldoc perlxs:
XS is an interface description file format used to create an
extension interface between Perl and C code (or a C library)
which one wishes to use with Perl. The XS interface is
combined with the library to create a new library which can
then be either dynamically loaded or statically linked into
perl. The XS interface description is written in the XS
language and is the core component of the Perl extension
interface.
The Perl API for the Mortally Terrified (beta)
XS is a specialized templating
language for C.
Some XS Code
Some XS Code

This stuff is XS.
Some C Code made by xsubpp
XS != Perl API
For most things
For most things
You don't actually
have to use XS.
(OK.You don’t have to
know that you’re using it.)
Inline::C
use Inline C;
hello('Mike');
hello('Cookie Monster');
__END__
__C__
void hello(char* name) {
  printf("Hello %s!n", name);
}
use Inline C;
hello('Mike');
hello('Grover');
__END__
__C__
void hello(char* name) {
  printf("Hello %s!n", name);
}
use Inline C;
hello('Mike');
hello('Grover');
__END__
__C__
void hello(char* name) {
  printf("Hello %s!n", name);
}
use Inline C;
hello('Mike');
hello('Grover');
__END__
__C__
void hello(char* name) {
  printf("Hello %s!n", name);
}
Inline::C Code in Perl
Inline::C Code in Perl
Digest::MD5
Inline::C Code in Perl
Digest::MD5
C Code

Parse::RecDescent
Inline::C Code in Perl
Digest::MD5
C Code

Parse::RecDescent

Create build in a temp dir
Inline::C Code in Perl
Digest::MD5
C Code

Parse::RecDescent

Create build in a temp dir
Write XS
Inline::C Code in Perl
Digest::MD5
C Code

Parse::RecDescent

Create build in a temp dir
Write XS
Compile and install
Inline::C Code in Perl
Digest::MD5
C Code

Parse::RecDescent

Create build in a temp dir
Write XS
Compile and install
How do we make
Perl do stuff in C?
How do we make
Perl do stuff in C?
We need to understand Perl’s data
structures.
Handwaving Ahead
A $scalar in Perl is represented by a struct called SV.
SvNULL

SvRV

SvPV

SvIV

(These are not all of them.)

SvNV
What does SV look like?
sv_refcnt

sv_flags

{

sv_any

flags

type
What does SV look like?
sv_refcnt

sv_flags

{

sv_any

flags

type

If this scalar is undef, then sv_any is NULL
What does SvPV (a string) look like?
sv_any

sv_refcnt

sv_flags

pvx

current len

alloc len

SV

xpv

char* a

s

t

r

i

n

g

0
What do SvIV and SvNV look like?
sv_any

sv_refcnt

sv_flags

pvx

current len

alloc len

SV

xpviv

69

7a

00

00

ivx
char* 3

1

3

3

7

0
What do SvIV and SvNV look like?
sv_any

sv_refcnt

sv_flags

pvx

current len

alloc len

SV

xpvnv

6e

86

1b

f0

f9

ivx
char* 3

.

21

09

40

nvx
1

4

1

5

9

0
WRITE CODE NOW
?!??!!11!?
Let's make
something fast.
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
int add( int a, int b ) {
return a + b;
}
Run it!
bash-3.2$ perl cexp1.pl
Give me a number: 42
Give me another number: 11
The sum is: 53
Run it again!
bash-3.2$ perl cexp1.pl
Give me a number: 42
Give me another number: 31.337
The sum is: 73
Run it again!
bash-3.2$ perl cexp1.pl
Give me a number: 42
Give me another number: 31.337
The sum is: 73
What happened?
Inline::C
is
CRAZY
SMART
int
int
int
int

Inline::C
is
CRAZY
SMART
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
$num_a += 0; $num_b += 0;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
SV *add( SV *a, SV *b ) {
if ( SvIOK( a ) && SvIOK( b ) ) {
return newSViv( SvIV( a ) + SvIV( b ) );
} else if ( SvNOK( a ) && SvNOK( b ) ) {
return newSVnv( SvNV( a ) + SvNV( b ) );
} else {
croak( "I don't know what to do!" );
}
}
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
$num_a += 0; $num_b += 0;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
SV *add( SV *a, SV *b ) {
if ( SvIOK( a ) && SvIOK( b ) ) {
return newSViv( SvIV( a ) + SvIV( b ) );
} else if ( SvNOK( a ) && SvNOK( b ) ) {
return newSVnv( SvNV( a ) + SvNV( b ) );
} else {
croak( "I don't know what to do!" );
}
}
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
$num_a += 0; $num_b += 0;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
SV *add( SV *a, SV *b ) {
if ( SvIOK( a ) && SvIOK( b ) ) {
return newSViv( SvIV( a ) + SvIV( b ) );
} else if ( SvNOK( a ) && SvNOK( b ) ) {
return newSVnv( SvNV( a ) + SvNV( b ) );
} else {
croak( "I don't know what to do!" );
}
}
use Inline 'C';
print 'Give me a number: ';
my $num_a = <STDIN>;
print 'Give me another number: ';
my $num_b = <STDIN>;
$num_a += 0; $num_b += 0;
printf "The sum is: %sn", add( $num_a, $num_b );
__END__
__C__
SV *add( SV *a, SV *b ) {
if ( SvIOK( a ) && SvIOK( b ) ) {
return newSViv( SvIV( a ) + SvIV( b ) );
} else if ( SvNOK( a ) && SvNOK( b ) ) {
return newSVnv( SvNV( a ) + SvNV( b ) );
} else {
croak( "I don't know what to do!" );
}
}
Run it!
bash-3.2$ perl cexp2.pl
Give me a number: 42
Give me another number: 11
The sum is: 53
bash-3.2$ perl cexp2.pl
Run it!
bash-3.2$ perl cexp2.pl
Give me a number: 42
Give me another number: 11
The sum is: 53
bash-3.2$ perl cexp2.pl
bash-3.2$ perl cexp2.pl
Give me a number: 53.4
Give me another number: 6.54
The sum is: 59.94
Run it!
bash-3.2$ perl cexp2.pl
Give me a number: 42
Give me another number: 11
The sum is: 53
bash-3.2$ perl cexp2.pl
bash-3.2$ perl cexp2.pl
Give me a number: 53.4
Give me another number: 6.54
The sum is: 59.94
Give me a number: 42
Give me another number: 6.54
I don't know what to do! at
cexp2.pl line 16, <STDIN>
line 2.
Once you get this far,
everything you need
is in perlapi.
Let's do something
with arrays.
What does an AV look like?
sv_any

sv_refcnt

sv_flags

array

fill

max

SV

xpvav

*some fields omitted

alloc

array len
SV

SV*[]
SV

...

...
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print "Give me some numbers: ";
my @numbers = map { $_ += 0 }
split /,/, <STDIN>;
my $result = squares( @numbers );
printf "The squares are: %sn",
join ", ", @$result;
__END__
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print "Give me some numbers: ";
my @numbers = map { $_ += 0 }
split /,/, <STDIN>;
my $result = squares( @numbers );
printf "The squares are: %sn",
join ", ", @$result;
__END__
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_inc( (SV *)return_array );
}
SV *squares( SV *numbers ) {
AV *array = (AV *)SvRV( numbers );
AV *return_array = newAV();
SV **tmp;
int len = AvFILL( array );
int i, val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvIOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvIV( *tmp );
val = val * val;
av_push( return_array, newSViv( val ) );
}
return newRV_noinc( (SV *)return_array );
}
Run it!
bash-3.2$ perl cexp3.pl
Give me some numbers: 4,5,6,23
The squares are: 16, 25, 36, 529
Let's do something
with hashes.
What does an HV look like?
What does an HV look like?
(Diagram missing
What does an HV look like?
(Diagram missing
(So I stole this one))
What does an HV look like?
(Diagram missing
(So I stole this one))
#!/usr/bin/env perl
use strict;
use warnings;
use Inline 'C';
print "Give me some words: ";
my @words = split /,/, <STDIN>;
chomp @words;
my $result = uniques( @words );
printf "The uniques are: %sn",
join ", ", %$result;
__END__
__C__
SV *uniques( SV *words ) {
AV *array = (AV *)SvRV( words );
HV *result = newHV();
SV **tmp;
int len = AvFILL( array );
int i;
char *val;
for( i = 0; i <= len; i++ ) {
tmp = av_fetch( array, i, 1 );
if( !SvPOK( *tmp ) ) {
croak( "Can't handle this value!" );
}
val = SvPV_nolen( *tmp );
hv_store( result, val, strlen( val ), newSV(0), 0 );
}
return newRV_noinc( (SV *)result );
}
Run it!
bash-3.2$ perl cexp4.pl
Give me some words: foo,bar,baz,baz,foo,quux,narf,poit
The uniques are: bar, narf, baz, poit, quux, foo
What is
Magic?
Not that terrifying.
Not that terrifying.
(code sample missing)
Magic is a linked list of function pointers
attached to a *SV.
Magic is a linked list of function pointers
attached to a *SV.
The functions implement custom read/write
behavior.
Magic is a linked list of function pointers
attached to a *SV.
The functions implement custom read/write
behavior.
Special vars like %ENV are implemented via
Magic.
$ENV{foo} = "blah";
$ENV{foo} = "blah";
assignment op
$ENV{foo} = "blah";
assignment op
Magic on %ENV ?
$ENV{foo} = "blah";
assignment op
Magic on %ENV ?

Look up write function
$ENV{foo} = "blah";
assignment op
Magic on %ENV ?

Look up write function

call libc setenv()
tie() is also implemented via Magic.
Terror defeated!
Where do we go from
here?
Resources:

perlguts
For details on how to manipulate Perl's
data structures.
Resources:

perlapi
For a comprehensive reference to (almost)
everything you need to make perl do stuff.
Resources:

Perlguts Illustrated
For pretty diagrams and explication.
Resources:

Inline::C Cookbook
For common solutions to problems
interfacing between Perl and C
Resources:
Resources:

Code samples
http://github.com/friedo/perl-api-terror
London Perl
Workshop
Thank you.
Mike Friedman
friedo@friedo.com
http://friedo.com/
http://github.com/friedo/perl-api-terror

More Related Content

PDF
Make Your Own Perl with Moops
ODP
Perl Moderno
ODP
What's new in Perl 5.10?
PDF
Perl.Hacks.On.Vim Perlchina
PDF
Perl.Hacks.On.Vim Perlchina
PDF
Good Evils In Perl
PDF
Perl.Hacks.On.Vim
PDF
Ruby 入門 第一次就上手
Make Your Own Perl with Moops
Perl Moderno
What's new in Perl 5.10?
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
Good Evils In Perl
Perl.Hacks.On.Vim
Ruby 入門 第一次就上手

What's hot (20)

PDF
Ruby 程式語言綜覽簡介
PDF
Just-In-Time Compiler in PHP 8
ODP
Red Flags in Programming
PDF
PHP7. Game Changer.
PDF
Perl 5.10
PDF
Create your own PHP extension, step by step - phpDay 2012 Verona
PDF
PHP7 is coming
PPTX
Php Extensions for Dummies
PDF
Debugging with pry
ODP
Embed--Basic PERL XS
PDF
PHP Enums - PHPCon Japan 2021
PDF
What's new in PHP 8.0?
PDF
An OCaml newbie meets Camlp4 parser
PDF
Nikita Popov "What’s new in PHP 8.0?"
PPTX
Php7 HHVM and co
PDF
Abuse Perl
PDF
How to write a TableGen backend
PDF
Static Optimization of PHP bytecode (PHPSC 2017)
PPT
Dealing with Legacy Perl Code - Peter Scott
PDF
Xtext Webinar
Ruby 程式語言綜覽簡介
Just-In-Time Compiler in PHP 8
Red Flags in Programming
PHP7. Game Changer.
Perl 5.10
Create your own PHP extension, step by step - phpDay 2012 Verona
PHP7 is coming
Php Extensions for Dummies
Debugging with pry
Embed--Basic PERL XS
PHP Enums - PHPCon Japan 2021
What's new in PHP 8.0?
An OCaml newbie meets Camlp4 parser
Nikita Popov "What’s new in PHP 8.0?"
Php7 HHVM and co
Abuse Perl
How to write a TableGen backend
Static Optimization of PHP bytecode (PHPSC 2017)
Dealing with Legacy Perl Code - Peter Scott
Xtext Webinar
Ad

Similar to The Perl API for the Mortally Terrified (beta) (20)

ODP
Getting started with Perl XS and Inline::C
PDF
perltut
PDF
perltut
ODP
Embedding perl
PDF
Perl_Part1
PDF
newperl5
PDF
newperl5
PDF
Cs3430 lecture 15
PPT
PERL.ppt
PPTX
Perl bhargav
PDF
Scripting3
PDF
Perl intro
PDF
Perl-C/C++ Integration with Swig
PDF
March2004-CPerlRun
PDF
March2004-CPerlRun
PDF
March2004-CPerlRun
PDF
March2004-CPerlRun
PPTX
KEY
Yapcasia2011 - Hello Embed Perl
Getting started with Perl XS and Inline::C
perltut
perltut
Embedding perl
Perl_Part1
newperl5
newperl5
Cs3430 lecture 15
PERL.ppt
Perl bhargav
Scripting3
Perl intro
Perl-C/C++ Integration with Swig
March2004-CPerlRun
March2004-CPerlRun
March2004-CPerlRun
March2004-CPerlRun
Yapcasia2011 - Hello Embed Perl
Ad

More from Mike Friedman (8)

PDF
Basic Symbolic Computation in Perl
PDF
21st Century CPAN Testing: CPANci
PPTX
Data Modeling for the Real World
PDF
CPANci: Continuous Integration for CPAN
PPTX
MongoDB Schema Design: Four Real-World Examples
PDF
Building a MongoDB App with Perl
PPTX
Building Your First App with MongoDB
KEY
Building Scalable, Distributed Job Queues with Redis and Redis::Client
Basic Symbolic Computation in Perl
21st Century CPAN Testing: CPANci
Data Modeling for the Real World
CPANci: Continuous Integration for CPAN
MongoDB Schema Design: Four Real-World Examples
Building a MongoDB App with Perl
Building Your First App with MongoDB
Building Scalable, Distributed Job Queues with Redis and Redis::Client

Recently uploaded (20)

PDF
Approach and Philosophy of On baking technology
PDF
cuic standard and advanced reporting.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPT
Teaching material agriculture food technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
Approach and Philosophy of On baking technology
cuic standard and advanced reporting.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
20250228 LYD VKU AI Blended-Learning.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Machine learning based COVID-19 study performance prediction
Reach Out and Touch Someone: Haptics and Empathic Computing
Diabetes mellitus diagnosis method based random forest with bat algorithm
Teaching material agriculture food technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Network Security Unit 5.pdf for BCA BBA.
“AI and Expert System Decision Support & Business Intelligence Systems”
NewMind AI Monthly Chronicles - July 2025
Digital-Transformation-Roadmap-for-Companies.pptx
Understanding_Digital_Forensics_Presentation.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Per capita expenditure prediction using model stacking based on satellite ima...
Advanced methodologies resolving dimensionality complications for autism neur...

The Perl API for the Mortally Terrified (beta)