.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" 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 .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . 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 .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PPIx::QuoteLike 3pm" .TH PPIx::QuoteLike 3pm "2021-02-15" "perl v5.32.1" "User Contributed Perl Documentation" .\" 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" PPIx::QuoteLike \- Parse Perl string literals and string\-literal\-like things. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use PPIx::QuoteLike; \& \& my $str = PPIx::QuoteLike\->new( q<"fu$bar"> ); \& say $str\->interpolates() ? \& \*(Aqinterpolates\*(Aq : \& \*(Aqdoes not interpolate\*(Aq; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This Perl class parses Perl string literals and things that are reasonably like string literals. Its real reason for being is to find interpolated variables for Perl::Critic policies and similar code. .PP The parse is fairly straightforward, and a little poking around with \&\fIeg/pqldump\fR should show how it normally goes. .PP But there is at least one quote-like thing that probably needs some explanation. .SS "Indented Here Documents" .IX Subsection "Indented Here Documents" These were introduced in Perl 5.25.7 (November 2016) but not recognized by this module until its version 0.015 (February 2021). The indentation is parsed as PPIx::QuoteLike::Token::Whitespace objects, provided it is at least one character wide, otherwise it is not represented in the parse. That is to say, .PP .Vb 4 \& <<~EOD \& How doth the little crocodile \& Improve his shining tail \& EOD .Ve .PP will have the three indentations represented by whitespace objects and each line of the literal represented by its own string object, but .PP .Vb 4 \& <<~EOD \& How doth the little crocodile \& Improve his shining tail \& EOD .Ve .PP will parse the same as the non-indented version, except for the addition of the token representing the \f(CW\*(Aq~\*(Aq\fR. .PP \&\s-1PPI\s0 is ahead of this module, and recognized indented here documents as of its version 1.246 (May 2019). Unfortunately, as of version 1.270 the indent gets lost in the parse, so a \f(CW\*(C`PPIx::QuoteLike\*(C'\fR object initialized from such a PPI::Token::HereDoc will be seen as having an indentation of \f(CW\*(Aq\*(Aq\fR regardless of the actual indentation in the source. I believe this restriction will go away when is resolved. .SH "DEPRECATION NOTICE" .IX Header "DEPRECATION NOTICE" The postderef argument to \fBnew()\fR is being put through a deprecation cycle and retracted. After the retraction, postfix dereferences will always be recognized. This is the default behaviour now. .PP Starting with version 0.012_01, the first use of this argument will warn. With the first release after April 8 2020, all uses will warn. After a further six months, all uses will become fatal. .SH "INHERITANCE" .IX Header "INHERITANCE" \&\f(CW\*(C`PPIx::QuoteLike\*(C'\fR is not descended from any other class. .PP \&\f(CW\*(C`PPIx::QuoteLike\*(C'\fR has no descendants. .SH "METHODS" .IX Header "METHODS" This class supports the following public methods: .SS "new" .IX Subsection "new" .Vb 1 \& my $str = PPIx::QuoteLike\->new( $source, %arg ); .Ve .PP This static method parses the argument, and returns a new object containing the parse. The \f(CW$source\fR argument can be either a scalar or an appropriate PPI::Element object. .PP If the \f(CW$source\fR argument is a scalar, it is presumed to represent a quote-like literal of some sort, provided it begins like one. Otherwise this method will return nothing. The scalar representation of a here document is a multi-line string whose first line consists of the leading \&\f(CW\*(C` << \*(C'\fR and the start delimiter, and whose subsequent lines consist of the content of the here document and the end delimiter. Indented here documents were not supported by this class until version \f(CW0.015\fR. .PP \&\f(CW\*(C`PPI\*(C'\fR classes that can be handled are PPI::Token::Quote, PPI::Token::QuoteLike::Backtick, PPI::Token::QuoteLike::Command, PPI::Token::QuoteLike::Readline, and PPI::Token::HereDoc. Any other object will cause \&\f(CW\*(C`new()\*(C'\fR to return nothing. .PP Additional optional arguments can be passed as name/value pairs. Supported arguments are: .IP "encoding" 4 .IX Item "encoding" This is the encoding of the \f(CW$source\fR. If this is specified as something other than \f(CW\*(C`undef\*(C'\fR, the \f(CW$source\fR will be decoded before processing. .Sp If the \f(CW$source\fR is a \f(CW\*(C`PPI::Element\*(C'\fR, this encoding is used only if the document that contains the element has neither a byte order mark nor \&\f(CW\*(Aquse utf8\*(Aq\fR. .IP "index_locations" 4 .IX Item "index_locations" This Boolean argument determines whether the locations of the tokens should be computed. It defaults to true if the \f(CW$source\fR argument is a PPI::Element or if the \f(CW\*(C`location\*(C'\fR argument was provided, and false otherwise. .IP "location" 4 .IX Item "location" This argument is a reference to an array compatible with that returned by the PPI::Element \fBlocation()\fR method. It defaults to the location of the \f(CW$source\fR argument if that was a PPI::Element, otherwise no locations will be available. .IP "postderef" 4 .IX Item "postderef" \&\fB\s-1THIS ARGUMENT IS DEPRECATED\s0\fR. See \s-1DEPRECATION NOTICE\s0 above for the details. .Sp This Boolean argument determines whether postfix dereferencing is recognized in interpolation. If unspecified, or specified as \f(CW\*(C`undef\*(C'\fR, it defaults to true. In version 0.012 it defaulted to the value of \&\f(CW$PPIx::QuoteLike::DEFAULT_POSTDEREF\fR. This variable was not exported, and was true by default. .IP "trace" 4 .IX Item "trace" This Boolean argument causes a trace of the parse to be written to standard out. Setting this to a true value is unsupported in the sense that the author makes no representation as to what will happen if you do it, and reserves the right to make changes to the functionality, or retract it completely, without notice. .PP All other arguments are unsupported and reserved to the author. .SS "child" .IX Subsection "child" .Vb 1 \& my $kid = $str\->child( 0 ); .Ve .PP This method returns the child element whose index is given as the argument. Children do not include the \fBtype()\fR, or the \&\fBstart()\fR or \fBfinish()\fR delimiters. Negative indices are valid, and given the usual Perl interpretation. .SS "children" .IX Subsection "children" .Vb 1 \& my @kids = $str\->children(); .Ve .PP This method returns all child elements. Children do not include the \&\fBtype()\fR, or the \fBstart()\fR or \fBfinish()\fR delimiters. .SS "column_number" .IX Subsection "column_number" This method returns the column number of the first character in the element, or \f(CW\*(C`undef\*(C'\fR if that can not be determined. .SS "content" .IX Subsection "content" .Vb 1 \& say $str\->content(); .Ve .PP This method returns the content of the object. If the original argument was a valid Perl string, this should be the same as the originally-parsed string. .SS "delimiters" .IX Subsection "delimiters" .Vb 1 \& say $str\->delimiters(); .Ve .PP This method returns the delimiters of the object, as a string. This will be two characters unless the argument to \fBnew()\fR was a here document, missing its end delimiter, or an invalid string. In the latter case the return might be anything. .SS "elements" .IX Subsection "elements" .Vb 1 \& my @elem = $str\->elements(); .Ve .PP This method returns all elements of the object. This includes \&\fBtype()\fR, \fBstart()\fR, \fBchildren()\fR, and \&\fBfinish()\fR, in that order. .SS "failures" .IX Subsection "failures" .Vb 1 \& say $str\->failures(); .Ve .PP This method returns the number of parse failures found. These are instances where the parser could not figure out what was going on, and should be the same as the number of PPIx::QuoteLike::Token::Unknown objects returned by \fBelements()\fR. .SS "find" .IX Subsection "find" .Vb 3 \& for ( @{[ $str\->find( $criteria ) || [] } ) { \& ... \& } .Ve .PP This method finds and returns a reference to an array of all elements that meet the given criteria. If nothing is found, a false value is returned. .PP The \f(CW$criteria\fR can be either the name of a PPIx::QuoteLike::Token class, or a code reference. In the latter case, the code is called for each element in \&\fBelements()\fR, with the element as the only argument. The element is included in the output if the code returns a true value. .SS "finish" .IX Subsection "finish" .Vb 1 \& say map { $_\->content() } $str\->finish(); .Ve .PP This method returns the finishing elements of the parse. It is actually an array, with the first element being a PPIx::QuoteLike::Token::Delimiter. If the parse is of a here document there will be a second element, which will be a PPIx::QuoteLike::Token::Whitespace containing the trailing new line character. .PP If called in list context you get the whole array. If called in scalar context you get the element whose index is given in the argument, or element zero if no argument is specified. .SS "handles" .IX Subsection "handles" .Vb 3 \& say PPIx::QuoteLike\->handles( $string ) ? \& "We can handle $string" : \& "We can not handle $string"; .Ve .PP This convenience static method returns a true value if this package can be expected to handle the content of \f(CW$string\fR (be it scalar or object), and a false value otherwise. .SS "indentation" .IX Subsection "indentation" This method returns the indentation string if the object represents an indented here document, or \f(CW\*(C`undef\*(C'\fR if it represents anything else, including an unindented here document. .PP \&\fBNote\fR that if indented syntax is used but the here document is not in fact indented, this will return \f(CW\*(Aq\*(Aq\fR, which evaluates to false. .SS "interpolates" .IX Subsection "interpolates" .Vb 3 \& say $str\->interpolates() ? \& \*(AqThe string interpolates\*(Aq : \& \*(AqThe string does not interpolate\*(Aq; .Ve .PP This method returns a true value if the parsed string interpolates, and a false value if it does not. This does \fBnot\fR indicate whether any interpolation actually takes place, only whether the string is double-quotish or single-quotish. .SS "line_number" .IX Subsection "line_number" This method returns the line number of the first character in the element, or \f(CW\*(C`undef\*(C'\fR if that can not be determined. .SS "location" .IX Subsection "location" This method returns a reference to an array describing the position of the string, or \f(CW\*(C`undef\*(C'\fR if the location is unavailable. .PP The array is compatible with the corresponding PPI::Element method. .SS "logical_filename" .IX Subsection "logical_filename" This method returns the logical file name (taking \f(CW\*(C`#line\*(C'\fR directives into account) of the file containing first character in the element, or \&\f(CW\*(C`undef\*(C'\fR if that can not be determined. .SS "logical_line_number" .IX Subsection "logical_line_number" This method returns the logical line number (taking \f(CW\*(C`#line\*(C'\fR directives into account) of the first character in the element, or \f(CW\*(C`undef\*(C'\fR if that can not be determined. .SS "parent" .IX Subsection "parent" This method returns nothing, since the invocant is only used at the top of the object hierarchy. .SS "perl_version_introduced" .IX Subsection "perl_version_introduced" This method returns the maximum value of \f(CW\*(C`perl_version_introduced\*(C'\fR returned by any of its elements. In other words, it returns the minimum version of Perl under which this quote-like object is valid. If there are no elements, 5.000 is returned, since that is the minimum value of Perl supported by this package. .SS "perl_version_removed" .IX Subsection "perl_version_removed" This method returns the minimum defined value of \f(CW\*(C`perl_version_removed\*(C'\fR returned by any of the quote-like object's elements. In other words, it returns the lowest version of Perl in which this object is \f(CW\*(C`not\*(C'\fR valid. If there are no elements, or if no element has a defined \&\f(CW\*(C`perl_version_removed\*(C'\fR, \f(CW\*(C`undef\*(C'\fR is returned. .SS "schild" .IX Subsection "schild" .Vb 1 \& my $skid = $str\->schild( 0 ); .Ve .PP This method returns the significant child elements whose index is given by the argument. Negative indices are interpreted in the usual way. .SS "schildren" .IX Subsection "schildren" .Vb 1 \& my @skids = $str\->schildren(); .Ve .PP This method returns the significant children. .SS "source" .IX Subsection "source" .Vb 1 \& my $source = $str\->source(); .Ve .PP This method returns the \f(CW$source\fR argument to \fBnew()\fR, whatever it was. .SS "start" .IX Subsection "start" .Vb 1 \& say map { $_\->content() } $str\->start(); .Ve .PP This method returns the starting elements of the parse. It is actually an array, with the first element being a PPIx::QuoteLike::Token::Delimiter. If the parse is of a here document there will be a second element, which will be a PPIx::QuoteLike::Token::Whitespace containing the trailing new line character. .PP If called in list context you get the whole array. If called in scalar context you get the element whose index is given in the argument, or element zero if no argument is specified. .SS "statement" .IX Subsection "statement" This method returns the PPI::Statement that contains this string, or nothing if the statement can not be determined. .PP In general this method will return something only under the following conditions: .IP "\(bu" 4 The string is contained in a PPIx::QuoteLike object; .IP "\(bu" 4 That object was initialized from a PPI::Element; .IP "\(bu" 4 The PPI::Element is contained in a statement. .SS "top" .IX Subsection "top" This method returns the top of the hierarchy \*(-- in this case, the invocant. .SS "type" .IX Subsection "type" .Vb 1 \& my $type = $str\->type(); .Ve .PP This method returns the type object. This will be a PPIx::QuoteLike::Token::Structure if the parse was successful; otherwise it might be \f(CW\*(C`undef\*(C'\fR. Its contents will be everything up to the start delimiter, and will typically be \f(CW\*(Aqq\*(Aq\fR, \f(CW\*(Aqqq\*(Aq\fR, \f(CW\*(Aqqx\*(Aq\fR, \f(CW \*(Aq<<\*(Aq \fR (for here documents), or \f(CW\*(Aq\*(Aq\fR (for quoted strings). .PP The type data are actually an array. If the second element is present it will be the white space (if any) separating the actual type from the value. If called in list context you get the whole array. If called in scalar context you get the element whose index is given in the argument, or element zero if no argument is specified. .SS "variables" .IX Subsection "variables" .Vb 1 \& say "Interpolates $_" for $str\->variables(); .Ve .PP \&\fB\s-1NOTE\s0\fR that this method is discouraged, and may well be deprecated and removed. My problem with it is that it returns variable names rather than PPI::Element objects, leaving you no idea how the variables are used. It was originally written for the benefit of Perl::Critic::Policy::Variables::ProhibitUnusedVarsStricter, but has proven inadequate to that policy's needs. .PP This convenience method returns all interpolated variables. Each is returned only once, and they are returned in no particular order. If the object does not represent a string that interpolates, nothing is returned. .SS "visual_column_number" .IX Subsection "visual_column_number" This method returns the visual column number (taking tabs into account) of the first character in the element, or \f(CW\*(C`undef\*(C'\fR if that can not be determined. .SH "RESTRICTIONS" .IX Header "RESTRICTIONS" By the nature of this module, it is never going to get everything right. Many of the known problem areas involve interpolations one way or another. .SS "Changes in Syntax" .IX Subsection "Changes in Syntax" Sometimes the introduction of new syntax changes the way a string is parsed. For example, the \f(CW\*(C`\eF\*(C'\fR (fold case) case control was introduced in Perl 5.15.8. But it did not represent a syntax error prior to that version of Perl, it was simply parsed as \f(CW\*(C`F\*(C'\fR. So .PP .Vb 1 \& $ perl \-le \*(Aqprint "Foo\eFBar"\*(Aq .Ve .PP prints \f(CW"FooFBar"\fR under Perl 5.14.4, but \f(CW"Foobar"\fR under 5.16.0. \&\f(CW\*(C`PPIx::QuoteLike\*(C'\fR generally assumes the more modern parse in cases like this. .SS "Static Parsing" .IX Subsection "Static Parsing" It is well known that Perl can not be statically parsed. That is, you can not completely parse a piece of Perl code without executing that same code. .PP Nevertheless, this class is trying to statically parse quote-like things. I do not have any examples of where the parse of a quote-like thing would change based on what is interpolated, but neither can I rule it out. \fICaveat user\fR. .SS "\s-1PPI\s0 Restrictions" .IX Subsection "PPI Restrictions" As of version 0.015 of this module, the only known instance of this is the handling of indented here documents, as discussed above under Indented Here Documents. .SS "Non-Standard Syntax" .IX Subsection "Non-Standard Syntax" There are modules out there that alter the syntax of Perl. If the syntax of a quote-like string is altered, this module has no way to understand that it has been altered, much less to adapt to the alteration. The following modules are known to cause problems: .PP Acme::PerlML, which renders Perl as \s-1XML.\s0 .PP \&\f(CW\*(C`Data::PostfixDeref\*(C'\fR, which causes Perl to interpret suffixed empty brackets as dereferencing the thing they suffix. This module by Ben Morrow (\f(CW\*(C`BMORROW\*(C'\fR) appears to have been retracted. .PP Filter::Trigraph, which recognizes \s-1ANSI C\s0 trigraphs, allowing Perl to be written in the \s-1ISO 646\s0 character set. .PP Perl6::Pugs. Enough said. .SH "SUPPORT" .IX Header "SUPPORT" Support is by the author. Please file bug reports at , or in electronic mail to the author. .SH "AUTHOR" .IX Header "AUTHOR" Thomas R. Wyant, \s-1III\s0 \fIwyant at cpan dot org\fR .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2016\-2021 by Thomas R. Wyant, \s-1III\s0 .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory \s-1LICENSES.\s0 .PP This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.