the perl api for the mortally terrified (beta)

154
The Perl API for the Mortally Terrified Mike Friedman (friedo) London Perl Workshop November 30, 2013

Upload: mike-friedman

Post on 10-May-2015

1.057 views

Category:

Technology


0 download

DESCRIPTION

A brief introduction to get you started in working with Perl's internal API. This presentation is a work in progress. Code samples: http://github.com/friedo/perl-api-terror

TRANSCRIPT

Page 1: The Perl API for the Mortally Terrified (beta)

The Perl APIfor the

Mortally Terrified

Mike Friedman(friedo)

London Perl WorkshopNovember 30, 2013

Page 2: The Perl API for the Mortally Terrified (beta)

MeMike Friedman

Page 3: The Perl API for the Mortally Terrified (beta)

Mike Friedman(friedo)

Page 4: The Perl API for the Mortally Terrified (beta)

This talk is the product of a lengthy journey.

Page 5: The Perl API for the Mortally Terrified (beta)

This talk is the product of a lengthy journey.

It's also a work in progress.

Page 6: The Perl API for the Mortally Terrified (beta)

I have some limited experience in integrating Perl and C with XS, and would enjoy the opportunity to expand my skills in this area.

Page 7: The Perl API for the Mortally Terrified (beta)

i R dum.

Page 8: The Perl API for the Mortally Terrified (beta)
Page 9: The Perl API for the Mortally Terrified (beta)

- Learned from this book.

Page 10: The Perl API for the Mortally Terrified (beta)

- Learned from this book.- It’s very good

Page 11: The Perl API for the Mortally Terrified (beta)

- Learned from this book.- It’s very good- The printing I got was messed up.

Page 12: The Perl API for the Mortally Terrified (beta)

- Learned from this book.- It’s very good- The printing I got was messed up.- Like every " was replaced by ©

Page 13: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make things fast:

Page 14: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make things fast: - Write your slow Perl code in C

Page 15: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make things fast: - Write your slow Perl code in C - Keep your fast Perl code in Perl

Page 16: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl more useful:

Page 17: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl more useful: - Interface with libraries written in C

Page 18: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl more useful: - Interface with libraries written in C - Create modules exposing external APIs to Perl

Page 19: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff

Page 20: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff - Change opcodes on the fly?

Page 21: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff - Change opcodes on the fly? - Extend the parser?

Page 22: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff - Change opcodes on the fly? - Extend the parser? - Make exceptions work?

Page 23: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff - Change opcodes on the fly? - Extend the parser? - Make exceptions work? - Why not?

Page 24: The Perl API for the Mortally Terrified (beta)

The Perl APIWhat’s it good for?

Make Perl do...stuff - Change opcodes on the fly? - Extend the parser? - Make exceptions work? - Why not?

Page 25: The Perl API for the Mortally Terrified (beta)

A Crash Course in

C

Page 26: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

Page 27: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

char foo = ‘a’;

Page 28: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

char foo = ‘a’;int bar = 42;

Page 29: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

char foo = ‘a’;int bar = 42;long baz = 198547;

Page 30: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

char foo = ‘a’;int bar = 42;long baz = 198547;float quux = 3.14159;

Page 31: The Perl API for the Mortally Terrified (beta)

C Crash Course

Basic Types (there are more)

char foo = ‘a’;int bar = 42;long baz = 198547;float quux = 3.14159;double splat = 3.14159265358979;

Page 32: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

Page 33: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */

Page 34: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */int *bar; /* ptr to int */

Page 35: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */int *bar; /* ptr to int */long *baz; /* ptr to long */

Page 36: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */int *bar; /* ptr to int */long *baz; /* ptr to long */float *quux; /* ptr to float */

Page 37: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */int *bar; /* ptr to int */long *baz; /* ptr to long */float *quux; /* ptr to float */double *splat; /* ptr to double */

Page 38: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers

char *foo; /* ptr to char */int *bar; /* ptr to int */long *baz; /* ptr to long */float *quux; /* ptr to float */double *splat; /* ptr to double */void *fnarf; /* ptr to something */

Page 39: The Perl API for the Mortally Terrified (beta)

C Crash Course

Pointers are integer variables which hold a memory address.

Page 40: The Perl API for the Mortally Terrified (beta)

C Crash Course

C Perl

Page 41: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;

C Perl

Page 42: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;int *i_ptr = &i; my $i_ref = \$i;

C Perl

Page 43: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;int *i_ptr = &i; my $i_ref = \$i;

Read unary & as “address-of.”

C Perl

Page 44: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;int *i_ptr = &i; my $i_ref = \$i;

Read unary & as “address-of.”

int j; my $j;

C Perl

Page 45: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;int *i_ptr = &i; my $i_ref = \$i;

Read unary & as “address-of.”

int j; my $j;j = *i_ptr; $j = $$i_ref;

C Perl

Page 46: The Perl API for the Mortally Terrified (beta)

C Crash Course

int i = 42; my $i = 42;int *i_ptr = &i; my $i_ref = \$i;

Read unary & as “address-of.”

int j; my $j;j = *i_ptr; $j = $$i_ref;

Read unary * as “dereference.”

C Perl

Page 47: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

Page 48: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

int foo[10]; /* array of ints */

Page 49: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

int foo[10]; /* array of ints */float bar[12]; /* array of floats */

Page 50: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

int foo[10]; /* array of ints */float bar[12]; /* array of floats */char baz[42]; /* a string! */

Page 51: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

Page 52: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregatesstruct person { int age; char *name; double acct_balance;};

Page 53: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregatesstruct person { int age; char *name; double acct_balance;};

age *name acct_balance

...

Page 54: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregates

Page 55: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregatesunion thingy { long num; char chars[4]; foo_t *myfoo;};

Page 56: The Perl API for the Mortally Terrified (beta)

C Crash Course

Aggregatesunion thingy { long num; char chars[4]; foo_t *myfoo;};

f3 de 42 9a

thingy.num

thingy.chars

thingy.myfoo

Page 57: The Perl API for the Mortally Terrified (beta)

C Crash Course

Using structs

Page 58: The Perl API for the Mortally Terrified (beta)

C Crash Course

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

Using structs

Page 59: The Perl API for the Mortally Terrified (beta)

C Crash Course

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

Using structs

00 2a 3f 39 d2 90 a4 70 3d 0a d7 a3 fc 3f

age *name acct_balance

j e f f r e y ...

Page 60: The Perl API for the Mortally Terrified (beta)

C Crash Course

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

person the_dude;

Page 61: The Perl API for the Mortally Terrified (beta)

XS

Page 62: The Perl API for the Mortally Terrified (beta)

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.

Page 63: The Perl API for the Mortally Terrified (beta)
Page 64: The Perl API for the Mortally Terrified (beta)

XS is a specialized templating language for C.

Page 65: The Perl API for the Mortally Terrified (beta)

Some XS Code

Page 66: The Perl API for the Mortally Terrified (beta)

Some XS Code

This stuff is XS.

Page 67: The Perl API for the Mortally Terrified (beta)

Some C Code made by xsubpp

Page 68: The Perl API for the Mortally Terrified (beta)

XS != Perl API

Page 69: The Perl API for the Mortally Terrified (beta)

For most things

Page 70: The Perl API for the Mortally Terrified (beta)

For most things

You don't actuallyhave to use XS.

Page 71: The Perl API for the Mortally Terrified (beta)

(OK. You don’t have to know that you’re using it.)

Page 72: The Perl API for the Mortally Terrified (beta)

Inline::C

Page 73: The Perl API for the Mortally Terrified (beta)

use Inline C;hello('Mike');hello('Cookie Monster');

__END__

__C__void hello(char* name) {  printf("Hello %s!\n", name);}

Page 74: The Perl API for the Mortally Terrified (beta)

use Inline C;hello('Mike');hello('Grover');

__END__

__C__void hello(char* name) {  printf("Hello %s!\n", name);}

Page 75: The Perl API for the Mortally Terrified (beta)

use Inline C;hello('Mike');hello('Grover');

__END__

__C__void hello(char* name) {  printf("Hello %s!\n", name);}

Page 76: The Perl API for the Mortally Terrified (beta)

use Inline C;hello('Mike');hello('Grover');

__END__

__C__void hello(char* name) {  printf("Hello %s!\n", name);}

Page 77: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Page 78: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

Page 79: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

C Code Parse::RecDescent

Page 80: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

Create build in a temp dir

C Code Parse::RecDescent

Page 81: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

Create build in a temp dir

C Code Parse::RecDescent

Write XS

Page 82: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

Create build in a temp dir

C Code Parse::RecDescent

Write XS

Compile and install

Page 83: The Perl API for the Mortally Terrified (beta)

Inline::C Code in Perl

Digest::MD5

Create build in a temp dir

C Code Parse::RecDescent

Write XS

Compile and install

Page 84: The Perl API for the Mortally Terrified (beta)

How do we make Perl do stuff in C?

Page 85: The Perl API for the Mortally Terrified (beta)

How do we make Perl do stuff in C?

We need to understand Perl’s data structures.

Page 86: The Perl API for the Mortally Terrified (beta)

Handwaving Ahead

Page 87: The Perl API for the Mortally Terrified (beta)

A $scalar in Perl is represented by a struct called SV.

SvNULL

SvRV SvNVSvPV SvIV

(These are not all of them.)

Page 88: The Perl API for the Mortally Terrified (beta)

What does SV look like?

sv_any sv_refcnt sv_flags

{

flags type

Page 89: The Perl API for the Mortally Terrified (beta)

What does SV look like?

sv_any sv_refcnt sv_flags

{

flags type

If this scalar is undef, then sv_any is NULL

Page 90: The Perl API for the Mortally Terrified (beta)

What does SvPV (a string) look like?

sv_any sv_refcnt sv_flags

SV

xpvpvx current len alloc len

a s t r i n gchar* \0

Page 91: The Perl API for the Mortally Terrified (beta)

What do SvIV and SvNV look like?

sv_any sv_refcnt sv_flags

SV

xpviv

pvx current len alloc len

3 1 3 3 7 \0char*

69 7a 00 00

ivx

Page 92: The Perl API for the Mortally Terrified (beta)

What do SvIV and SvNV look like?

sv_any sv_refcnt sv_flags

SV

xpvnv

pvx current len alloc len

3 . 1 4 1 5char*

6e 86 1b f0

ivxf9 21 09 40

nvx

9 \0

Page 93: The Perl API for the Mortally Terrified (beta)

WRITE CODE NOW?!??!!11!?

Page 94: The Perl API for the Mortally Terrified (beta)

Let's make something fast.

Page 95: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 96: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 97: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 98: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 99: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 100: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", add( $num_a, $num_b );__END____C__

int add( int a, int b ) { return a + b;}

Page 101: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp1.plGive me a number: 42Give me another number: 11The sum is: 53

Run it!

Page 102: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp1.plGive me a number: 42Give me another number: 31.337The sum is: 73

Run it again!

Page 103: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp1.plGive me a number: 42Give me another number: 31.337The sum is: 73

Run it again!

What happened?

Page 104: The Perl API for the Mortally Terrified (beta)

Inline::C is

CRAZY SMART

Page 105: The Perl API for the Mortally Terrified (beta)

intintintint

Inline::C is

CRAZY SMART

Page 106: The Perl API for the Mortally Terrified (beta)

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: %s\n", 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!" ); }}

Page 107: The Perl API for the Mortally Terrified (beta)

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: %s\n", 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!" ); }}

Page 108: The Perl API for the Mortally Terrified (beta)

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: %s\n", 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!" ); }}

Page 109: The Perl API for the Mortally Terrified (beta)

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: %s\n", 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!" ); }}

Page 110: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp2.pl Give me a number: 42Give me another number: 11The sum is: 53bash-3.2$ perl cexp2.pl

Run it!

Page 111: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp2.pl Give me a number: 42Give me another number: 11The sum is: 53bash-3.2$ perl cexp2.pl

Run it!

bash-3.2$ perl cexp2.pl Give me a number: 53.4Give me another number: 6.54The sum is: 59.94

Page 112: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp2.pl Give me a number: 42Give me another number: 11The sum is: 53bash-3.2$ perl cexp2.pl

Run it!

bash-3.2$ perl cexp2.pl Give me a number: 53.4Give me another number: 6.54The sum is: 59.94

Give me a number: 42Give me another number: 6.54I don't know what to do! at cexp2.pl line 16, <STDIN> line 2.

Page 113: The Perl API for the Mortally Terrified (beta)

Once you get this far, everything you need

is in perlapi.

Page 114: The Perl API for the Mortally Terrified (beta)

Let's do something with arrays.

Page 115: The Perl API for the Mortally Terrified (beta)

What does an AV look like?

sv_any sv_refcnt sv_flags

SV

xpvav

array fill max

SV*[]

alloc array len*some fields omitted

SV ...

SV ...

Page 116: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", join ", ", @$result;

__END__

Page 117: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", join ", ", @$result;

__END__

Page 118: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 119: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 120: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 121: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 122: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 123: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 124: The Perl API for the Mortally Terrified (beta)

__C__

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 );}

Page 125: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp3.pl Give me some numbers: 4,5,6,23The squares are: 16, 25, 36, 529

Run it!

Page 126: The Perl API for the Mortally Terrified (beta)

Let's do something with hashes.

Page 127: The Perl API for the Mortally Terrified (beta)

What does an HV look like?

Page 128: The Perl API for the Mortally Terrified (beta)

What does an HV look like?

(Diagram missing

Page 129: The Perl API for the Mortally Terrified (beta)

What does an HV look like?

(Diagram missing

(So I stole this one))

Page 130: The Perl API for the Mortally Terrified (beta)

What does an HV look like?

(Diagram missing

(So I stole this one))

Page 131: The Perl API for the Mortally Terrified (beta)

#!/usr/bin/env perluse 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: %s\n", join ", ", %$result;

__END__

Page 132: The Perl API for the Mortally Terrified (beta)

__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 );}

Page 133: The Perl API for the Mortally Terrified (beta)

bash-3.2$ perl cexp4.pl Give me some words: foo,bar,baz,baz,foo,quux,narf,poitThe uniques are: bar, narf, baz, poit, quux, foo

Run it!

Page 134: The Perl API for the Mortally Terrified (beta)

What isMagic?

Page 135: The Perl API for the Mortally Terrified (beta)

Not that terrifying.

Page 136: The Perl API for the Mortally Terrified (beta)

Not that terrifying.(code sample missing)

Page 137: The Perl API for the Mortally Terrified (beta)

Magic is a linked list of function pointers attached to a *SV.

Page 138: The Perl API for the Mortally Terrified (beta)

Magic is a linked list of function pointers attached to a *SV.

The functions implement custom read/write behavior.

Page 139: The Perl API for the Mortally Terrified (beta)

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.

Page 140: The Perl API for the Mortally Terrified (beta)

$ENV{foo} = "blah";

Page 141: The Perl API for the Mortally Terrified (beta)

$ENV{foo} = "blah";

assignment op

Page 142: The Perl API for the Mortally Terrified (beta)

$ENV{foo} = "blah";

Magic on %ENV ?

assignment op

Page 143: The Perl API for the Mortally Terrified (beta)

$ENV{foo} = "blah";

Magic on %ENV ?

assignment op

Look up write function

Page 144: The Perl API for the Mortally Terrified (beta)

$ENV{foo} = "blah";

Magic on %ENV ?

assignment op

Look up write function

call libc setenv()

Page 145: The Perl API for the Mortally Terrified (beta)

tie() is also implemented via Magic.

Page 146: The Perl API for the Mortally Terrified (beta)

Terror defeated!

Page 147: The Perl API for the Mortally Terrified (beta)

Where do we go from here?

Page 148: The Perl API for the Mortally Terrified (beta)

Resources:

perlgutsFor details on how to manipulate Perl's

data structures.

Page 149: The Perl API for the Mortally Terrified (beta)

Resources:

perlapiFor a comprehensive reference to (almost)

everything you need to make perl do stuff.

Page 150: The Perl API for the Mortally Terrified (beta)

Resources:

Perlguts Illustrated

For pretty diagrams and explication.

Page 151: The Perl API for the Mortally Terrified (beta)

Resources:

Inline::C Cookbook

For common solutions to problemsinterfacing between Perl and C

Page 152: The Perl API for the Mortally Terrified (beta)

Resources:

Page 153: The Perl API for the Mortally Terrified (beta)

Resources:

Code samples

http://github.com/friedo/perl-api-terror

Page 154: The Perl API for the Mortally Terrified (beta)

London Perl Workshop

Thank you.

Mike [email protected]

http://friedo.com/http://github.com/friedo/perl-api-terror