diff options
Diffstat (limited to 'upstream/mageia-cauldron/man3pm/B::Deparse.3pm')
-rw-r--r-- | upstream/mageia-cauldron/man3pm/B::Deparse.3pm | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man3pm/B::Deparse.3pm b/upstream/mageia-cauldron/man3pm/B::Deparse.3pm new file mode 100644 index 00000000..bc40ec5c --- /dev/null +++ b/upstream/mageia-cauldron/man3pm/B::Deparse.3pm @@ -0,0 +1,540 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "B::Deparse 3pm" +.TH B::Deparse 3pm 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +B::Deparse \- Perl compiler backend to produce perl code +.SH SYNOPSIS +.IX Header "SYNOPSIS" +\&\fBperl\fR \fB\-MO=Deparse\fR[\fB,\-d\fR][\fB,\-f\fR\fIFILE\fR][\fB,\-p\fR][\fB,\-q\fR][\fB,\-l\fR] + [\fB,\-s\fR\fILETTERS\fR][\fB,\-x\fR\fILEVEL\fR] \fIprog.pl\fR +.SH DESCRIPTION +.IX Header "DESCRIPTION" +B::Deparse is a backend module for the Perl compiler that generates +perl source code, based on the internal compiled structure that perl +itself creates after parsing a program. The output of B::Deparse won't +be exactly the same as the original source, since perl doesn't keep +track of comments or whitespace, and there isn't a one-to-one +correspondence between perl's syntactical constructions and their +compiled form, but it will often be close. When you use the \fB\-p\fR +option, the output also includes parentheses even when they are not +required by precedence, which can make it easy to see if perl is +parsing your expressions the way you intended. +.PP +While B::Deparse goes to some lengths to try to figure out what your +original program was doing, some parts of the language can still trip +it up; it still fails even on some parts of Perl's own test suite. If +you encounter a failure other than the most common ones described in +the BUGS section below, you can help contribute to B::Deparse's +ongoing development by submitting a bug report with a small +example. +.SH OPTIONS +.IX Header "OPTIONS" +As with all compiler backend options, these must follow directly after +the '\-MO=Deparse', separated by a comma but not any white space. +.IP \fB\-d\fR 4 +.IX Item "-d" +Output data values (when they appear as constants) using Data::Dumper. +Without this option, B::Deparse will use some simple routines of its +own for the same purpose. Currently, Data::Dumper is better for some +kinds of data (such as complex structures with sharing and +self-reference) while the built-in routines are better for others +(such as odd floating-point values). +.IP \fB\-f\fR\fIFILE\fR 4 +.IX Item "-fFILE" +Normally, B::Deparse deparses the main code of a program, and all the subs +defined in the same file. To include subs defined in +other files, pass the \fB\-f\fR option with the filename. +You can pass the \fB\-f\fR option several times, to +include more than one secondary file. (Most of the time you don't want to +use it at all.) You can also use this option to include subs which are +defined in the scope of a \fB#line\fR directive with two parameters. +.IP \fB\-l\fR 4 +.IX Item "-l" +Add '#line' declarations to the output based on the line and file +locations of the original code. +.IP \fB\-p\fR 4 +.IX Item "-p" +Print extra parentheses. Without this option, B::Deparse includes +parentheses in its output only when they are needed, based on the +structure of your program. With \fB\-p\fR, it uses parentheses (almost) +whenever they would be legal. This can be useful if you are used to +LISP, or if you want to see how perl parses your input. If you say +.Sp +.Vb 3 +\& if ($var & 0x7f == 65) {print "Gimme an A!"} +\& print ($which ? $a : $b), "\en"; +\& $name = $ENV{USER} or "Bob"; +.Ve +.Sp +\&\f(CW\*(C`B::Deparse,\-p\*(C'\fR will print +.Sp +.Vb 5 +\& if (($var & 0)) { +\& print(\*(AqGimme an A!\*(Aq) +\& }; +\& (print(($which ? $a : $b)), \*(Aq???\*(Aq); +\& (($name = $ENV{\*(AqUSER\*(Aq}) or \*(Aq???\*(Aq) +.Ve +.Sp +which probably isn't what you intended (the \f(CW\*(Aq???\*(Aq\fR is a sign that +perl optimized away a constant value). +.IP \fB\-P\fR 4 +.IX Item "-P" +Disable prototype checking. With this option, all function calls are +deparsed as if no prototype was defined for them. In other words, +.Sp +.Vb 1 +\& perl \-MO=Deparse,\-P \-e \*(Aqsub foo (\e@) { 1 } foo @x\*(Aq +.Ve +.Sp +will print +.Sp +.Vb 4 +\& sub foo (\e@) { +\& 1; +\& } +\& &foo(\e@x); +.Ve +.Sp +making clear how the parameters are actually passed to \f(CW\*(C`foo\*(C'\fR. +.IP \fB\-q\fR 4 +.IX Item "-q" +Expand double-quoted strings into the corresponding combinations of +concatenation, uc, ucfirst, lc, lcfirst, quotemeta, and join. For +instance, print +.Sp +.Vb 1 +\& print "Hello, $world, @ladies, \eu$gentlemen\eE, \eu\eL$me!"; +.Ve +.Sp +as +.Sp +.Vb 2 +\& print \*(AqHello, \*(Aq . $world . \*(Aq, \*(Aq . join($", @ladies) . \*(Aq, \*(Aq +\& . ucfirst($gentlemen) . \*(Aq, \*(Aq . ucfirst(lc $me . \*(Aq!\*(Aq); +.Ve +.Sp +Note that the expanded form represents the way perl handles such +constructions internally \-\- this option actually turns off the reverse +translation that B::Deparse usually does. On the other hand, note that +\&\f(CW\*(C`$x = "$y"\*(C'\fR is not the same as \f(CW\*(C`$x = $y\*(C'\fR: the former makes the value +of \f(CW$y\fR into a string before doing the assignment. +.IP \fB\-s\fR\fILETTERS\fR 4 +.IX Item "-sLETTERS" +Tweak the style of B::Deparse's output. The letters should follow +directly after the 's', with no space or punctuation. The following +options are available: +.RS 4 +.IP \fBC\fR 4 +.IX Item "C" +Cuddle \f(CW\*(C`elsif\*(C'\fR, \f(CW\*(C`else\*(C'\fR, and \f(CW\*(C`continue\*(C'\fR blocks. For example, print +.Sp +.Vb 5 +\& if (...) { +\& ... +\& } else { +\& ... +\& } +.Ve +.Sp +instead of +.Sp +.Vb 6 +\& if (...) { +\& ... +\& } +\& else { +\& ... +\& } +.Ve +.Sp +The default is not to cuddle. +.IP \fBi\fR\fINUMBER\fR 4 +.IX Item "iNUMBER" +Indent lines by multiples of \fINUMBER\fR columns. The default is 4 columns. +.IP \fBT\fR 4 +.IX Item "T" +Use tabs for each 8 columns of indent. The default is to use only spaces. +For instance, if the style options are \fB\-si4T\fR, a line that's indented +3 times will be preceded by one tab and four spaces; if the options were +\&\fB\-si8T\fR, the same line would be preceded by three tabs. +.IP \fBv\fR\fISTRING\fR\fB.\fR 4 +.IX Item "vSTRING." +Print \fISTRING\fR for the value of a constant that can't be determined +because it was optimized away (mnemonic: this happens when a constant +is used in \fBv\fRoid context). The end of the string is marked by a period. +The string should be a valid perl expression, generally a constant. +Note that unless it's a number, it probably needs to be quoted, and on +a command line quotes need to be protected from the shell. Some +conventional values include 0, 1, 42, '', 'foo', and +\&'Useless use of constant omitted' (which may need to be +\&\fB\-sv"'Useless use of constant omitted'."\fR +or something similar depending on your shell). The default is '???'. +If you're using B::Deparse on a module or other file that's require'd, +you shouldn't use a value that evaluates to false, since the customary +true constant at the end of a module will be in void context when the +file is compiled as a main program. +.RE +.RS 4 +.RE +.IP \fB\-x\fR\fILEVEL\fR 4 +.IX Item "-xLEVEL" +Expand conventional syntax constructions into equivalent ones that expose +their internal operation. \fILEVEL\fR should be a digit, with higher values +meaning more expansion. As with \fB\-q\fR, this actually involves turning off +special cases in B::Deparse's normal operations. +.Sp +If \fILEVEL\fR is at least 3, \f(CW\*(C`for\*(C'\fR loops will be translated into equivalent +while loops with continue blocks; for instance +.Sp +.Vb 3 +\& for ($i = 0; $i < 10; ++$i) { +\& print $i; +\& } +.Ve +.Sp +turns into +.Sp +.Vb 6 +\& $i = 0; +\& while ($i < 10) { +\& print $i; +\& } continue { +\& ++$i +\& } +.Ve +.Sp +Note that in a few cases this translation can't be perfectly carried back +into the source code \-\- if the loop's initializer declares a my variable, +for instance, it won't have the correct scope outside of the loop. +.Sp +If \fILEVEL\fR is at least 5, \f(CW\*(C`use\*(C'\fR declarations will be translated into +\&\f(CW\*(C`BEGIN\*(C'\fR blocks containing calls to \f(CW\*(C`require\*(C'\fR and \f(CW\*(C`import\*(C'\fR; for +instance, +.Sp +.Vb 1 +\& use strict \*(Aqrefs\*(Aq; +.Ve +.Sp +turns into +.Sp +.Vb 6 +\& sub BEGIN { +\& require strict; +\& do { +\& \*(Aqstrict\*(Aq\->import(\*(Aqrefs\*(Aq) +\& }; +\& } +.Ve +.Sp +If \fILEVEL\fR is at least 7, \f(CW\*(C`if\*(C'\fR statements will be translated into +equivalent expressions using \f(CW\*(C`&&\*(C'\fR, \f(CW\*(C`?:\*(C'\fR and \f(CW\*(C`do {}\*(C'\fR; for instance +.Sp +.Vb 9 +\& print \*(Aqhi\*(Aq if $nice; +\& if ($nice) { +\& print \*(Aqhi\*(Aq; +\& } +\& if ($nice) { +\& print \*(Aqhi\*(Aq; +\& } else { +\& print \*(Aqbye\*(Aq; +\& } +.Ve +.Sp +turns into +.Sp +.Vb 3 +\& $nice and print \*(Aqhi\*(Aq; +\& $nice and do { print \*(Aqhi\*(Aq }; +\& $nice ? do { print \*(Aqhi\*(Aq } : do { print \*(Aqbye\*(Aq }; +.Ve +.Sp +Long sequences of elsifs will turn into nested ternary operators, which +B::Deparse doesn't know how to indent nicely. +.SH "USING B::Deparse AS A MODULE" +.IX Header "USING B::Deparse AS A MODULE" +.SS Synopsis +.IX Subsection "Synopsis" +.Vb 4 +\& use B::Deparse; +\& $deparse = B::Deparse\->new("\-p", "\-sC"); +\& $body = $deparse\->coderef2text(\e&func); +\& eval "sub func $body"; # the inverse operation +.Ve +.SS Description +.IX Subsection "Description" +B::Deparse can also be used on a sub-by-sub basis from other perl +programs. +.SS new +.IX Subsection "new" +.Vb 1 +\& $deparse = B::Deparse\->new(OPTIONS) +.Ve +.PP +Create an object to store the state of a deparsing operation and any +options. The options are the same as those that can be given on the +command line (see "OPTIONS"); options that are separated by commas +after \fB\-MO=Deparse\fR should be given as separate strings. +.SS ambient_pragmas +.IX Subsection "ambient_pragmas" +.Vb 1 +\& $deparse\->ambient_pragmas(strict => \*(Aqall\*(Aq, \*(Aq$[\*(Aq => $[); +.Ve +.PP +The compilation of a subroutine can be affected by a few compiler +directives, \fBpragmas\fR. These are: +.IP \(bu 4 +use strict; +.IP \(bu 4 +use warnings; +.IP \(bu 4 +Assigning to the special variable $[ +.IP \(bu 4 +use integer; +.IP \(bu 4 +use bytes; +.IP \(bu 4 +use utf8; +.IP \(bu 4 +use re; +.PP +Ordinarily, if you use B::Deparse on a subroutine which has +been compiled in the presence of one or more of these pragmas, +the output will include statements to turn on the appropriate +directives. So if you then compile the code returned by coderef2text, +it will behave the same way as the subroutine which you deparsed. +.PP +However, you may know that you intend to use the results in a +particular context, where some pragmas are already in scope. In +this case, you use the \fBambient_pragmas\fR method to describe the +assumptions you wish to make. +.PP +Not all of the options currently have any useful effect. See +"BUGS" for more details. +.PP +The parameters it accepts are: +.IP strict 4 +.IX Item "strict" +Takes a string, possibly containing several values separated +by whitespace. The special values "all" and "none" mean what you'd +expect. +.Sp +.Vb 1 +\& $deparse\->ambient_pragmas(strict => \*(Aqsubs refs\*(Aq); +.Ve +.IP $[ 4 +Takes a number, the value of the array base $[. +Obsolete: cannot be non-zero. +.IP bytes 4 +.IX Item "bytes" +.PD 0 +.IP utf8 4 +.IX Item "utf8" +.IP integer 4 +.IX Item "integer" +.PD +If the value is true, then the appropriate pragma is assumed to +be in the ambient scope, otherwise not. +.IP re 4 +.IX Item "re" +Takes a string, possibly containing a whitespace-separated list of +values. The values "all" and "none" are special. It's also permissible +to pass an array reference here. +.Sp +.Vb 1 +\& $deparser\->ambient_pragmas(re => \*(Aqeval\*(Aq); +.Ve +.IP warnings 4 +.IX Item "warnings" +Takes a string, possibly containing a whitespace-separated list of +values. The values "all" and "none" are special, again. It's also +permissible to pass an array reference here. +.Sp +.Vb 1 +\& $deparser\->ambient_pragmas(warnings => [qw[void io]]); +.Ve +.Sp +If one of the values is the string "FATAL", then all the warnings +in that list will be considered fatal, just as with the \fBwarnings\fR +pragma itself. Should you need to specify that some warnings are +fatal, and others are merely enabled, you can pass the \fBwarnings\fR +parameter twice: +.Sp +.Vb 4 +\& $deparser\->ambient_pragmas( +\& warnings => \*(Aqall\*(Aq, +\& warnings => [FATAL => qw/void io/], +\& ); +.Ve +.Sp +See warnings for more information about lexical warnings. +.IP hint_bits 4 +.IX Item "hint_bits" +.PD 0 +.IP warning_bits 4 +.IX Item "warning_bits" +.PD +These two parameters are used to specify the ambient pragmas in +the format used by the special variables $^H and ${^WARNING_BITS}. +.Sp +They exist principally so that you can write code like: +.Sp +.Vb 7 +\& { my ($hint_bits, $warning_bits); +\& BEGIN {($hint_bits, $warning_bits) = ($^H, ${^WARNING_BITS})} +\& $deparser\->ambient_pragmas ( +\& hint_bits => $hint_bits, +\& warning_bits => $warning_bits, +\& \*(Aq$[\*(Aq => 0 + $[ +\& ); } +.Ve +.Sp +which specifies that the ambient pragmas are exactly those which +are in scope at the point of calling. +.IP %^H 4 +.IX Item "%^H" +This parameter is used to specify the ambient pragmas which are +stored in the special hash %^H. +.SS coderef2text +.IX Subsection "coderef2text" +.Vb 2 +\& $body = $deparse\->coderef2text(\e&func) +\& $body = $deparse\->coderef2text(sub ($$) { ... }) +.Ve +.PP +Return source code for the body of a subroutine (a block, optionally +preceded by a prototype in parens), given a reference to the +sub. Because a subroutine can have no names, or more than one name, +this method doesn't return a complete subroutine definition \-\- if you +want to eval the result, you should prepend "sub subname ", or "sub " +for an anonymous function constructor. Unless the sub was defined in +the main:: package, the code will include a package declaration. +.SH BUGS +.IX Header "BUGS" +.IP \(bu 4 +The only pragmas to +be completely supported are: \f(CW\*(C`use warnings\*(C'\fR, +\&\f(CW\*(C`use strict\*(C'\fR, \f(CW\*(C`use bytes\*(C'\fR, \f(CW\*(C`use integer\*(C'\fR +and \f(CW\*(C`use feature\*(C'\fR. +.Sp +Excepting those listed above, we're currently unable to guarantee that +B::Deparse will produce a pragma at the correct point in the program. +(Specifically, pragmas at the beginning of a block often appear right +before the start of the block instead.) +Since the effects of pragmas are often lexically scoped, this can mean +that the pragma holds sway over a different portion of the program +than in the input file. +.IP \(bu 4 +In fact, the above is a specific instance of a more general problem: +we can't guarantee to produce BEGIN blocks or \f(CW\*(C`use\*(C'\fR declarations in +exactly the right place. So if you use a module which affects compilation +(such as by over-riding keywords, overloading constants or whatever) +then the output code might not work as intended. +.IP \(bu 4 +Some constants don't print correctly either with or without \fB\-d\fR. +For instance, neither B::Deparse nor Data::Dumper know how to print +dual-valued scalars correctly, as in: +.Sp +.Vb 1 +\& use constant E2BIG => ($!=7); $y = E2BIG; print $y, 0+$y; +\& +\& use constant H => { "#" => 1 }; H\->{"#"}; +.Ve +.IP \(bu 4 +An input file that uses source filtering probably won't be deparsed into +runnable code, because it will still include the \fBuse\fR declaration +for the source filtering module, even though the code that is +produced is already ordinary Perl which shouldn't be filtered again. +.IP \(bu 4 +Optimized-away statements are rendered as +\&'???'. This includes statements that +have a compile-time side-effect, such as the obscure +.Sp +.Vb 1 +\& my $x if 0; +.Ve +.Sp +which is not, consequently, deparsed correctly. +.Sp +.Vb 3 +\& foreach my $i (@_) { 0 } +\& => +\& foreach my $i (@_) { \*(Aq???\*(Aq } +.Ve +.IP \(bu 4 +Lexical (my) variables declared in scopes external to a subroutine +appear in coderef2text output text as package variables. This is a tricky +problem, as perl has no native facility for referring to a lexical variable +defined within a different scope, although PadWalker is a good start. +.Sp +See also Data::Dump::Streamer, which combines B::Deparse and +PadWalker to serialize closures properly. +.IP \(bu 4 +There are probably many more bugs on non-ASCII platforms (EBCDIC). +.SH AUTHOR +.IX Header "AUTHOR" +Stephen McCamant <smcc@CSUA.Berkeley.EDU>, based on an earlier version +by Malcolm Beattie <mbeattie@sable.ox.ac.uk>, with contributions from +Gisle Aas, James Duncan, Albert Dvornik, Robin Houston, Dave Mitchell, +Hugo van der Sanden, Gurusamy Sarathy, Nick Ing-Simmons, and Rafael +Garcia-Suarez. |