PApp::PCode - PCode compiler/decompiler and various other utility functions.


   use PApp::PCode;

   eval pcode2perl perl2pcode "pcode";
   eval pcode2perl pxml2pcode "pcode";
   eval pcode2perl xml2pcode "pcode";


PApp stores a lot of things in pcode format, which is simply an escaping mechanism to store pxml/xml/html/perl sections inside a single data structure that can be efficiently converted to pxml or perl code.

You will rarely if ever need to use this module directly.

pxml2pcode "phtml or pxml code"

Protect the contents of the phtml or pxml string (xml with embedded perl sections), i.e. make it an xml-parseable-document by resolving all <: and <? sections.

The following four mode-switches are allowed, the initial mode is ":>" (i.e. non-interpolated html/xml). You can force the initial mode to ":>" by prefixing the string with "<:?>".

 <:     start verbatim perl section ("perl-mode")
 :>     start plain string section (non-interpolated string)
 <?     start perl expression (single expr, result will be interpolated)
 ?>     illegal(!) (was deprecated before)


Within plain and interpolated string sections you can also use the __"string" construct to mark (and map) internationalized text. The construct must be used verbatim: two underlines, one double-quote, text, and a trailing double-quote. For more complex uses, just escape to perl (e.g. <?__"xxx":>).


In string sections (and only there!), you can also use preprocessor commands (the # must be at the beginning of the line, between the # and the command name can be any amount of white space, just like in C!)

 #if any_perl_condition
   any phtml code
 #elsif any_perl_conditon

Preprocessor-commands are ignored at the very beginning of a string section (that is, they must follow a linebreak). They are completely removed on output (i.e. the linebreak before and after it will not be reflected in the output).

White space will be mostly preserved (especially line-number and -ordering).

CALLBACKS ("{: xxx :}(args)")

Within perl sections, one can automatically create PApp::Callback objects by enclosing code in {: and :} pairs. This creates a PApp::Callback object from the enclosed code fragment. A refer will be created automatically If the closing bracket is followed by an opening parenthesis, e.g.:

 # callback object alone
 my $cb = {: print "hallo" :};

 # callback & refer
 surl {: warn "called with $_[0]" :}(55);

Implementation: a callback of the form "{:code:}(args)" will be compiled like this (which might change anytime).

 +do {
    BEGIN {
       $_some_global_var = {{register_function}} sub { {{callback_preamble}} code }, name => "hash";
       # hash is a hash of the code, i.e. code changes => callback changes.

An experimental facility (a.k.a. hack and subject to change!) to overwrite all parts marked as {{}} is available: The global variable


contains a hash with strings for all marked parts of a callback. Remember that the function is being called when the code is eval'ed. A valid trick to pass extra context information is to store something like funcname 5,6, as the callback name.

xml2pcode "string"

Convert the string into pcode without interpreting it.

perl2pcode "perl source"

Protect the given perl sourcecode, i.e. convert it in a similar way as pxml_to_pcode, registering any callbacks it sees.

pcode2perl $pcode

Convert the protected xml/perl code into vanilla perl that can be eval'ed. The result will have the same number of lines (in the same order) as the original perl or xml source (important for error reporting).




 Marc Lehmann <>