WARNING
This is a draft
Todo:
- Data type comparison Perl/ETF/Bert
- Low level Perl data-structure review
- High level implementation with pack and unpack
- Perl unit testing
- Low level C implementation (etf.h)
- ETF encoding specification rules
- Update Github repository
- NIF interface?
- Erlang as Perl interpreter?
On last article we have connected Erlang to a C node. C is between the low and the high level language. In this article I will show you how to export data from Erlang to Perl. Perl don’t support BERT or ETF natively. No support was made by the community.
So, why Perl?
- Perl core
- Portability
- Data structure
- Documentation/Bibliography
- Community
Perl is an interesting language, IT guys doesn’t like it because of its syntax and probably due to its artistic side but, in fact, Perl core (interpreter) is fantastic! Another reason is due to its diffusion. This language run almost everywhere, you can use it on old server/desktop workstation, on any kind of operating system.
Why not python or ruby? For many reasons. Python2 and 3 are non-compatible currently, and its a PITA to make something working on these two languages. Python already support BERT, so, I will not learn more than using a framework, not my purpose. I don’t know Ruby. I’ve wrote some script with it, but, never do more. Ruby already support BERT like Python.
A little part of history, Perl was made by Larry Wall in 1987. Perl5 was released in 1994 and since, its the current release for every Perl program.
About Perl6
# High Level Perl
Before starting our High Level Perl implementation, we need to understand some functions. Perl love text patterns, this language was made to make regular expression easier in code. Well, Perl doesn’t like binary patterns. For extracting values from some arbitrary binary patterns, we need to learn pack and unpack functions.
pack first argument is a string containing defined term, all others
arguments are data to encode. Okay, it’s not clear. I will give you
the opposite. In perl, we can represent binary value like a list of
characters. All specials one (non-printable), can be created with
\x{Number} where number is an hexadecimal integer. Just to make
thing easier to understand, you can try to execute something like
that:
perl -e 'printf("\\x{42}\\x{43}\\x{a}");'
\# will print:
\# BC
Okay, we know how to generate arbitrary binary string based on
character. So, now, a binary string, like its name want to say, is
only 0 and 1 , we can interpret those two numbers in multiple
ways. Its where pack can help us. Our latest example show you how to
generate string, and, fortunately, this string is mainly composed of
ASCII printable character and only with one non-printable character (
\x{a} is \n or line feed). \x{42} could represent B character
or the integer value 0x42 coded on 8bits. We can also interpret that
in another way. \x{42}\x{43} can be see as list of characters (a
string) with value BC or it could be see as an 16bits integer with
0x4243as value if we use big-endian encoding or 0x4342 in
little-endian encoding.
pack and unpack are here to help us! Those two functions are using
something like pattern matching to extract some comprehensible data
from binary string. We’ll extract our data as characters:
perl -e 'my ($b\_char, $c\_char)=unpack("cc","\\x{42}\\x{43}\\x{a}");
printf("b: %c, c: %c\\n", $b\_char, $c\_char);'
\# will print
\# b: B, c: C
Okay, now, we want to extract them as char 8bit integers:
perl -e 'my ($b\_char, $c\_char)=unpack("CC","\\x{42}\\x{43}\\x{a}");
printf("b: %d, c: %d\\n", $b\_char, $c\_char);'
\# will print
\# b: 66, c: 67
Well, in this case, it’s pretty the same, except we have only modified printf format string and print extracted value as integers. So, and for 16bits integers?
perl -e 'my $integer =unpack("s","\\x{42}\\x{43}\\x{a}");
printf("integer: %d\\n", $integer);'
\# will print
\# integer: 17218
In this particular case, depending on your system, you’ll could see if
you are using big or little-endian format, but, you can also force
this behavior and interpret those binary values in your own way. To
read the first 16bits in little-endian you can use n for “network”.
perl -e 'my $integer = unpack("n","\\x{42}\\x{43}\\x{a}");
printf("integer: %d\\n", $integer);'
\# will print
\# integer: 16963
If you want to read those 16bits in big-endian, you can use v for VAX.
perl -e 'my $integer = unpack("v","\\x{42}\\x{43}\\x{a}");
printf("integer: %d\\n", $integer);'
\# will print
\# integer: 17218
# Low Level Perl
Perl is an interpreted language, and like every other interpreted language, it transpose and convert plaintext source-code to a binary one, reads by Perl interpreter and finally executed. To do this, Perl has multiple data-structure. If you have some Perl knowledge, you already knows some of them. Before listing Perl internal structure, we also need to understand some concept. Perl is an Object Oriented language, you can make objects and interact with them.
| Perl type | ETF | BERT |
|---|---|---|
| undef | ||
| integer | ||
| float | ||
| reference | ||
| string | ||
| magic | ||
| array | ||
| hash | ||
| code | ||
| glob |
- http://perldoc.perl.org/functions/map.html (opens new window)
- http://perldoc.perl.org/functions/grep.html (opens new window)
- http://perldoc.perl.org/functions/tie.html (opens new window)
- http://perldoc.perl.org/Tie/Array.html (opens new window)
- http://perldoc.perl.org/perltie.html (opens new window)
- http://perldoc.perl.org/functions/unpack.html (opens new window)
- http://perldoc.perl.org/functions/pack.html (opens new window)
- http://perldoc.perl.org/Test/Simple.html (opens new window)
- https://github.com/openbsd/src/tree/master/gnu/usr.bin/perl (opens new window)
# References & Bibliography
- Erlang External Term Format Documentation (opens new window)
- Perl Internals Documentation (opens new window)
- Perl Pack Tutorial (opens new window)
- Extending and Embedding Perl (opens new window) — Tim Jenness and Simon Cozens
- Programming Perl (opens new window) — Tom Christiansen, Jon Orwant, Larry Wall and Brian Foy
- Perl Best Practices (opens new window)— Damian Conway
- Perl Testing: A Developer’s Notebook (opens new window) — Shane Warden and Ian Langworth
- The Garbage Collection Handbook (opens new window) — Richard Jones, Antony Hosking and Eliot Moss
- High Order Perl (opens new window) — Mark Jason Dominus (pdf (opens new window) and epub (opens new window) freely available)
- Upload to CPAN — https://pause.perl.org/pause/ (opens new window)