perl-diddler has asked for the wisdom of the Perl Monks concerning the following question:

I was looking over the PPI set of modules and am wondering if anyone uses it in the format:
# Create a document from source $Document = PPI::Document->new(\'print "Hello World!\n"');
I've tried several variations using vars, double and single quotes, but have been unable to get it to parse anything from memory. It *does* work if I give it a file, but the example above doesn't seems to work -- which seems pretty basic.

I'm wanting to use it for memory-based input and no files are involved, For example, I might want to parse the same line 2 different ways (maybe with a trailing semicolon, or w/o, or some other way).

I'm wondering what syntax is suppose to work -- I also pointed out that the documented example doesn't work in their issue database, but no response on that. So does anyone have any working examples? My basic framework (in a file called ppi_dump) looks like:

#!/usr/bin/perl use warnings; use strict; # use utf8; use open IN=>q(:utf8); use open OUT=>q(:utf8); use PPI; use PPI::Dumper; use P; P "parse: %s", $ARGV[0]; my $doc=PPI::Document->new($ARGV[0]); my $dumpr=PPI::Dumper->new($doc, qw(whitespace 0 comments 0)); # .my $toks = $dumpr->list; # for indirect access... $dumpr->print;

A working example should suffice to jumpstart this -- from the documentation, I would have thought a string would have worked for my "arg", like:

> ppi_dump 'print "Hello World!\n"' parse: print "Hello World!\n" Can't call method "list" on an undefined value at ./ppi_dump line 14.

FWIW, if I give it a filename, it shows the content of the file, parsed, but the parse from string is the issue.

Tnx...

Replies are listed 'Best First'.
Re: PPI usage w/r/t documentation
by Athanasius (Archbishop) on Aug 28, 2016 at 04:26 UTC

    Hello perl-diddler,

    I have no experience with the PPI modules, but I can get (a slightly simplified version of) your code to work by adding a backslash before $ARGV[0] in the call to PPI::Document->new:

    #! perl use warnings; use strict; use PPI; use PPI::Dumper; printf "parse: >%s<\n", $ARGV[0]; my $doc = PPI::Document->new(\$ARGV[0]) or die "PPI::Document->new failed: $!"; my $dumpr = PPI::Dumper->new($doc) or die "PPI::Dumper->new failed: $!"; $dumpr->print;

    Output:

    14:25 >perl 1688_SoPW.pl "print qq[Hello world!\n];" parse: >print qq[Hello world!\n];< PPI::Document PPI::Statement PPI::Token::Word 'print' PPI::Token::Whitespace ' ' PPI::Token::Quote::Interpolate 'qq[Hello world!\n]' PPI::Token::Structure ';' 14:25 >

    Note that it’s good practice to die on failure: in this case, it identifies the call to PPI::Document->new as the location of the problem.

    Also note that I use double quotes on the command line because I’m on Windows.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Ah...it needs the address of the string or var....doi!

      Tnx!

Re: PPI usage w/r/t documentation
by stevieb (Canon) on Aug 28, 2016 at 14:46 UTC

    Ahh, PPI. Great distribution... the best Perl parser next to perl itself :)

    The first example should work without issue (passing in a reference to a string of Perl code). If you are saying the first example fails for you, please keep reading. If you are saying it DOES work for you, but only doesn't work when you use a var to wrap it, then I was just slightly misunderstood the issue, and the rest of this post is kind of invalid. The $ARGV[0] example was corrected by Athanasius, by sending in a reference to $ARGV[0] instead of sending it in directly.

    Could you please try the below code and see if it compares to my output below? If it doesn't, can you please let us know, 1) Operating System and version, 2) perl version, 3) PPI version.

    use warnings; use strict; use PPI; use PPI::Dumper; # string { my $doc = PPI::Document->new( \'print "hello, world!\n"' ) or die $!; print $doc->find_first('PPI::Statement') ."\n"; my $dumpr = PPI::Dumper->new($doc, qw(whitespace 0 comments 0)); $dumpr->print; } # string within scalar { my $run = 'print "goodbye, world!\n"'; my $doc = PPI::Document->new(\$run) or die $!; print $doc->find_first('PPI::Statement') ."\n"; my $dumpr = PPI::Dumper->new($doc, qw(whitespace 0 comments 0)); $dumpr->print; }

    Output:

    print "hello, world!\n" PPI::Document PPI::Statement PPI::Token::Word 'print' PPI::Token::Quote::Double '"hello, world!\n"' print "goodbye, world!\n" PPI::Document PPI::Statement PPI::Token::Word 'print' PPI::Token::Quote::Double '"goodbye, world!\n"'