SlideShare ist ein Scribd-Unternehmen logo
1 von 154
Downloaden Sie, um offline zu lesen
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.
- 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.
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

Weitere ähnliche Inhalte

Was ist angesagt?

Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
Wen-Tien Chang
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
Elizabeth Smith
 
Debugging with pry
Debugging with pryDebugging with pry
Debugging with pry
Creditas
 

Was ist angesagt? (20)

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

Ähnlich wie The Perl API for the Mortally Terrified (beta)

Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 

Ähnlich wie The Perl API for the Mortally Terrified (beta) (20)

Cleancode
CleancodeCleancode
Cleancode
 
Perl Presentation
Perl PresentationPerl Presentation
Perl Presentation
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
 
Anacronia on speed
Anacronia on speedAnacronia on speed
Anacronia on speed
 
Embedding perl
Embedding perlEmbedding perl
Embedding perl
 
Beginning Perl
Beginning PerlBeginning Perl
Beginning Perl
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
You Can Do It! Start Using Perl to Handle Your Voyager Needs
You Can Do It! Start Using Perl to Handle Your Voyager NeedsYou Can Do It! Start Using Perl to Handle Your Voyager Needs
You Can Do It! Start Using Perl to Handle Your Voyager Needs
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 

Mehr von Mike Friedman

Mehr von Mike Friedman (8)

Basic Symbolic Computation in Perl
Basic Symbolic Computation in PerlBasic Symbolic Computation in Perl
Basic Symbolic Computation in Perl
 
21st Century CPAN Testing: CPANci
21st Century CPAN Testing: CPANci21st Century CPAN Testing: CPANci
21st Century CPAN Testing: CPANci
 
Data Modeling for the Real World
Data Modeling for the Real WorldData Modeling for the Real World
Data Modeling for the Real World
 
CPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPANCPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPAN
 
MongoDB Schema Design: Four Real-World Examples
MongoDB Schema Design: Four Real-World ExamplesMongoDB Schema Design: Four Real-World Examples
MongoDB Schema Design: Four Real-World Examples
 
Building a MongoDB App with Perl
Building a MongoDB App with PerlBuilding a MongoDB App with Perl
Building a MongoDB App with Perl
 
Building Your First App with MongoDB
Building Your First App with MongoDBBuilding Your First App with MongoDB
Building Your First App with MongoDB
 
Building Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::ClientBuilding Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::Client
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Kürzlich hochgeladen (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

The Perl API for the Mortally Terrified (beta)