SlideShare a Scribd company logo
1 of 161
Download to read offline
The Perl API
for the
Mortally Terrified
Mike Friedman
YAPC::NA 2014
Orlando, FL
@friedo
This talk
is the product of a lengthy journey.
The Perl API
What’s it good for?
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?
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.
XS is a specialized templating
language for C.
Some XS Code
Some XS Code
XS
Directives
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
Create build in a temp dir
C Code Parse::RecDescent
Inline::C Code in Perl
Digest::MD5
Create build in a temp dir
C Code Parse::RecDescent
Write XS
Inline::C Code in Perl
Digest::MD5
Create build in a temp dir
C Code Parse::RecDescent
Write XS
Compile and install
Inline::C Code in Perl
Digest::MD5
Create build in a temp dir
C Code Parse::RecDescent
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 SvNVSvPV SvIV
(These are not all of them.)
What does SV look like?
ANY
What does SV look like?
Points to a struct with the scalar's metadata.
ANY
What does SV look like?
What does SV look like?
REFCNT
What does SV look like?
Reference count for garbage collection
REFCNT
What does SV look like?
What does SV look like?
FLAGS TYPE
What does SV look like?
Flags and type information
FLAGS TYPE
What does SV look like?
What does SV look like?
SV_U
What does SV look like?
Points to a union with the actual scalar's data
SV_U
What does SV look like?
What does SV look like?
What does SV look like?
The simplest scalar:
undef
What does SV look like?
The simplest scalar:
undef
The "ANY" pointer is NULL, and TYPE is zero.
undef is, like, totes boring.
What about strings?
What does SV look like?
What does SV look like?
Strings
What does SV look like?
Strings
"ANY" points to a "xpv", and TYPE is 4.*
* in Perl 5.20.
What does SV look like?
Strings
"ANY" points to a "xpv", and TYPE is 4.*
* in Perl 5.20.
SV becomes SvPV
What does SV look like?
What does SV look like?
Integers
What does SV look like?
Integers
"ANY" points to a "xpviv", and TYPE is 1.*
* in Perl 5.20.
What does SV look like?
Integers
"ANY" points to a "xpviv", and TYPE is 1.*
* in Perl 5.20.
SV becomes SvIV
What does SV look like?
What does SV look like?
Floats
What does SV look like?
Floats
"ANY" points to a "xpvnv", and TYPE is 2.*
* in Perl 5.20.
What does SV look like?
Floats
"ANY" points to a "xpvnv", and TYPE is 2.*
* in Perl 5.20.
SV becomes SvNV
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;
}
bash-3.2$ perl cexp1.pl
Give me a number: 42
Give me another number: 11
The sum is: 53
Run it!
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
Run it again!
What happened?
Inline::C
is
CRAZY
SMART
int
int
int
int
Inline::C
is
CRAZY
SMART
Adding numbers:
What will we need?
•SvIOK Is it a SvIV?
•SvIOK Is it a SvIV?
•SvNOK Is it a SvNV?
•SvIOK Is it a SvIV?
•SvNOK Is it a SvNV?
•SvIV Get the C int value from SV
•SvIOK Is it a SvIV?
•SvNOK Is it a SvNV?
•SvIV Get the C int value from SV
•SvNV Get the C float value from SV
•SvIOK Is it a SvIV?
•SvNOK Is it a SvNV?
•SvIV Get the C int value from SV
•SvNV Get the C float value from SV
•newSViv Make a new integer SV
•SvIOK Is it a SvIV?
•SvNOK Is it a SvNV?
•SvIV Get the C int value from SV
•SvNV Get the C float value from SV
•newSViv Make a new integer SV
•newSVnv Make a new float SV
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; # coerce
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!" );
}
}
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
Run it!
bash-3.2$ perl cexp2.pl
Give me a number: 53.4
Give me another number: 6.54
The sum is: 59.94
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: 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 SV look like?
What does SV look like?
Arrays
What does SV look like?
Arrays
"ANY" points to a "xpvav"
What does SV look like?
Arrays
"ANY" points to a "xpvav"
SV becomes AV
Squaring numbers:
What will we need?
•SvRV Get SV from reference
•SvRV Get SV from reference
•newAV Make a new array AV
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•AvFILL Get size of array
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvIOK Is it an int?
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvIOK Is it an int?
•SvIV Get C int from SV
•SvRV Get SV from reference
•newAV Make a new array AV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvIOK Is it an int?
•SvIV Get C int from SV
•av_push Obvs.
#!/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( (SV *)return_array );
}
bash-3.2$ perl cexp3.pl
Give me some numbers: 4,5,6,23
The squares are: 16, 25, 36, 529
Run it!
Let's do something
with hashes.
What does SV look like?
What does SV look like?
Hashes
What does SV look like?
Hashes
"ANY" points to a "xpvhv"
What does SV look like?
Hashes
"ANY" points to a "xpvhv"
SV becomes HV
Finding uniques:
What will we need?
•SvRV Get SV from reference
•SvRV Get SV from reference
•newHV Make a new hash HV
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•AvFILL Get size of array
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvPOK Is it a string?
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvPOK Is it a string?
•SvPV Get C string from SV
•SvRV Get SV from reference
•newHV Make a new hash HV
•newRV Make a new reference
•AvFILL Get size of array
•av_fetch Get an element from array
•SvPOK Is it a string?
•SvPV Get C string from SV
•hv_store Obvs.
#!/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( (SV *)result );
}
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
Run it!
What is
Magic?
Not that terrifying.
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";
Magic on %ENV ?
assignment op
$ENV{foo} = "blah";
Magic on %ENV ?
assignment op
Look up write function
$ENV{foo} = "blah";
Magic on %ENV ?
assignment op
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
YAPC::NA
Thank you.
Mike Friedman
friedo@friedo.com
http://friedo.com/
http://github.com/friedo/perl-api-terror

More Related Content

Recently uploaded

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 

Recently uploaded (20)

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 

Featured

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

The Perl API for the Mortally Terrified

  • 1. The Perl API for the Mortally Terrified Mike Friedman YAPC::NA 2014 Orlando, FL @friedo
  • 2. This talk is the product of a lengthy journey.
  • 3. The Perl API What’s it good for?
  • 4. The Perl API What’s it good for? Make things fast:
  • 5. The Perl API What’s it good for? Make things fast: - Write your slow Perl code in C
  • 6. 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
  • 7. The Perl API What’s it good for? Make Perl more useful:
  • 8. The Perl API What’s it good for? Make Perl more useful: - Interface with libraries written in C
  • 9. 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
  • 10. The Perl API What’s it good for? Make Perl do...stuff
  • 11. The Perl API What’s it good for? Make Perl do...stuff - Change opcodes on the fly?
  • 12. The Perl API What’s it good for? Make Perl do...stuff - Change opcodes on the fly? - Extend the parser?
  • 13. The Perl API What’s it good for? Make Perl do...stuff - Change opcodes on the fly? - Extend the parser? - Make exceptions work?
  • 14. 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?
  • 15. 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?
  • 16. XS
  • 17. 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.
  • 18.
  • 19. XS is a specialized templating language for C.
  • 22. Some C Code made by xsubpp
  • 23. XS != Perl API
  • 25. For most things You don't actually have to use XS.
  • 26. (OK.You don’t have to know that you’re using it.)
  • 28. use Inline C; hello('Mike'); hello('Cookie Monster'); __END__ __C__ void hello(char* name) {   printf("Hello %s!n", name); }
  • 29. use Inline C; hello('Mike'); hello('Grover'); __END__ __C__ void hello(char* name) {   printf("Hello %s!n", name); }
  • 30. use Inline C; hello('Mike'); hello('Grover'); __END__ __C__ void hello(char* name) {   printf("Hello %s!n", name); }
  • 31. use Inline C; hello('Mike'); hello('Grover'); __END__ __C__ void hello(char* name) {   printf("Hello %s!n", name); }
  • 33. Inline::C Code in Perl Digest::MD5
  • 34. Inline::C Code in Perl Digest::MD5 C Code Parse::RecDescent
  • 35. Inline::C Code in Perl Digest::MD5 Create build in a temp dir C Code Parse::RecDescent
  • 36. Inline::C Code in Perl Digest::MD5 Create build in a temp dir C Code Parse::RecDescent Write XS
  • 37. Inline::C Code in Perl Digest::MD5 Create build in a temp dir C Code Parse::RecDescent Write XS Compile and install
  • 38. Inline::C Code in Perl Digest::MD5 Create build in a temp dir C Code Parse::RecDescent Write XS Compile and install
  • 39. How do we make Perl do stuff in C?
  • 40. How do we make Perl do stuff in C? We need to understand Perl’s data structures.
  • 42. A $scalar in Perl is represented by a struct called SV. SvNULL SvRV SvNVSvPV SvIV (These are not all of them.)
  • 43. What does SV look like? ANY
  • 44. What does SV look like? Points to a struct with the scalar's metadata. ANY
  • 45. What does SV look like?
  • 46. What does SV look like? REFCNT
  • 47. What does SV look like? Reference count for garbage collection REFCNT
  • 48. What does SV look like?
  • 49. What does SV look like? FLAGS TYPE
  • 50. What does SV look like? Flags and type information FLAGS TYPE
  • 51. What does SV look like?
  • 52. What does SV look like? SV_U
  • 53. What does SV look like? Points to a union with the actual scalar's data SV_U
  • 54. What does SV look like?
  • 55. What does SV look like?
  • 56. What does SV look like? The simplest scalar: undef
  • 57. What does SV look like? The simplest scalar: undef The "ANY" pointer is NULL, and TYPE is zero.
  • 58. undef is, like, totes boring.
  • 60. What does SV look like?
  • 61. What does SV look like? Strings
  • 62. What does SV look like? Strings "ANY" points to a "xpv", and TYPE is 4.* * in Perl 5.20.
  • 63. What does SV look like? Strings "ANY" points to a "xpv", and TYPE is 4.* * in Perl 5.20. SV becomes SvPV
  • 64. What does SV look like?
  • 65. What does SV look like? Integers
  • 66. What does SV look like? Integers "ANY" points to a "xpviv", and TYPE is 1.* * in Perl 5.20.
  • 67. What does SV look like? Integers "ANY" points to a "xpviv", and TYPE is 1.* * in Perl 5.20. SV becomes SvIV
  • 68. What does SV look like?
  • 69. What does SV look like? Floats
  • 70. What does SV look like? Floats "ANY" points to a "xpvnv", and TYPE is 2.* * in Perl 5.20.
  • 71. What does SV look like? Floats "ANY" points to a "xpvnv", and TYPE is 2.* * in Perl 5.20. SV becomes SvNV
  • 74. #!/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; }
  • 75. #!/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; }
  • 76. #!/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; }
  • 77. #!/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; }
  • 78. #!/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; }
  • 79. #!/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; }
  • 80. bash-3.2$ perl cexp1.pl Give me a number: 42 Give me another number: 11 The sum is: 53 Run it!
  • 81. bash-3.2$ perl cexp1.pl Give me a number: 42 Give me another number: 31.337 The sum is: 73 Run it again!
  • 82. bash-3.2$ perl cexp1.pl Give me a number: 42 Give me another number: 31.337 The sum is: 73 Run it again! What happened?
  • 86.
  • 87. •SvIOK Is it a SvIV?
  • 88. •SvIOK Is it a SvIV? •SvNOK Is it a SvNV?
  • 89. •SvIOK Is it a SvIV? •SvNOK Is it a SvNV? •SvIV Get the C int value from SV
  • 90. •SvIOK Is it a SvIV? •SvNOK Is it a SvNV? •SvIV Get the C int value from SV •SvNV Get the C float value from SV
  • 91. •SvIOK Is it a SvIV? •SvNOK Is it a SvNV? •SvIV Get the C int value from SV •SvNV Get the C float value from SV •newSViv Make a new integer SV
  • 92. •SvIOK Is it a SvIV? •SvNOK Is it a SvNV? •SvIV Get the C int value from SV •SvNV Get the C float value from SV •newSViv Make a new integer SV •newSVnv Make a new float SV
  • 93. 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!" ); } }
  • 94. 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; # coerce 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!" ); } }
  • 95. 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!" ); } }
  • 96. 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!" ); } }
  • 97. 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!
  • 98. 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: 53.4 Give me another number: 6.54 The sum is: 59.94
  • 99. 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: 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.
  • 100. Once you get this far, everything you need is in perlapi.
  • 102. What does SV look like?
  • 103. What does SV look like? Arrays
  • 104. What does SV look like? Arrays "ANY" points to a "xpvav"
  • 105. What does SV look like? Arrays "ANY" points to a "xpvav" SV becomes AV
  • 107. •SvRV Get SV from reference
  • 108. •SvRV Get SV from reference •newAV Make a new array AV
  • 109. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference
  • 110. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference •AvFILL Get size of array
  • 111. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array
  • 112. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvIOK Is it an int?
  • 113. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvIOK Is it an int? •SvIV Get C int from SV
  • 114. •SvRV Get SV from reference •newAV Make a new array AV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvIOK Is it an int? •SvIV Get C int from SV •av_push Obvs.
  • 115. #!/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__
  • 116. #!/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__
  • 117. 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 ); }
  • 118. 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 ); }
  • 119. 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 ); }
  • 120. 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 ); }
  • 121. 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 ); }
  • 122. 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 ); }
  • 123. 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( (SV *)return_array ); }
  • 124. bash-3.2$ perl cexp3.pl Give me some numbers: 4,5,6,23 The squares are: 16, 25, 36, 529 Run it!
  • 126. What does SV look like?
  • 127. What does SV look like? Hashes
  • 128. What does SV look like? Hashes "ANY" points to a "xpvhv"
  • 129. What does SV look like? Hashes "ANY" points to a "xpvhv" SV becomes HV
  • 131. •SvRV Get SV from reference
  • 132. •SvRV Get SV from reference •newHV Make a new hash HV
  • 133. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference
  • 134. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference •AvFILL Get size of array
  • 135. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array
  • 136. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvPOK Is it a string?
  • 137. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvPOK Is it a string? •SvPV Get C string from SV
  • 138. •SvRV Get SV from reference •newHV Make a new hash HV •newRV Make a new reference •AvFILL Get size of array •av_fetch Get an element from array •SvPOK Is it a string? •SvPV Get C string from SV •hv_store Obvs.
  • 139. #!/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__
  • 140. __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( (SV *)result ); }
  • 141. 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 Run it!
  • 144. Magic is a linked list of function pointers attached to a *SV.
  • 145. Magic is a linked list of function pointers attached to a *SV. The functions implement custom read/write behavior.
  • 146. 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.
  • 149. $ENV{foo} = "blah"; Magic on %ENV ? assignment op
  • 150. $ENV{foo} = "blah"; Magic on %ENV ? assignment op Look up write function
  • 151. $ENV{foo} = "blah"; Magic on %ENV ? assignment op Look up write function call libc setenv()
  • 152. tie() is also implemented via Magic.
  • 154. Where do we go from here?
  • 155. Resources: perlguts For details on how to manipulate Perl's data structures.
  • 156. Resources: perlapi For a comprehensive reference to (almost) everything you need to make perl do stuff.
  • 157. Resources: Perlguts Illustrated For pretty diagrams and explication.
  • 158. Resources: Inline::C Cookbook For common solutions to problems interfacing between Perl and C