Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Greetings! I have a simple Perl script that uses PPI to locate and update the heredocs (which is mainly SQL) in Perl scripts/modules. For each heredoc in the script/module it clipboards the content of the heredoc and allows you to change it. For most respect it is well-behaved except when it comes to the heredoc terminators - which double (in the sense that what should be EOF becomes EOFEOF). When the fed the script and replacing "Something" with "else"
my($query); $query =<<"ENDOFSQL"; Something ENDOFSQL $query = <<"ENDOFSQL"; Something ENDOFSQL
I'll get
my($query); $query =<<"ENDOFSQL"; /* # Just A Test Something */ else ENDOFSQLENDOFSQL $query = <<"ENDOFSQL"; /* # Just A Test Something */ else ENDOFSQLENDOFSQL
Note the doubling up of the terminators. Here is FindAndUpdateHeredoc script
#!/usr/bin/perl use 5.12.0; use Params::Validate qw(:all); use PPI; use PPI::Dumper; use PPI::Find; use Win32::Clipboard; use strict; use warnings; # Clear the screen system 'cls'; FindAndReplaceHereDocs($ARGV[0],"$ARGV[0].upd") if (-f $ARGV[0]); exit; sub _Comment { return "# Just A Test"; }; sub FindAndReplaceHereDocs { @_=Params::Validate::validate_pos(@_ ,{ type=>SCALAR, callbacks=>{ "File not found"=> sub { + -f shift() } }} ,{ type=>SCALAR } ,{ type=>SCALAR, optional=>1, default=>_Comment() }); ### @_ my ($ExistingCodeFilename_S,$UpdatedCodeFilename_S,$Comment_S) +=@_; my $Document_o=PPI::Document->new($ExistingCodeFilename_S); #PPI::Dumper->new($Document_o,whitespace=>0,locations=>1)->pri +nt; # Stripping out comments #$Document_o->prune('PPI::Token::Comment'); # Sub to find HereDocs local *HereDocs = sub { $_[1]->isa('PPI::Token::HereDoc') }; # Buffer for HereDocs required by the updated document my @NewHereDoc_a; # We'll need a clipboard ... my $Clipboard_o=Win32::Clipboard->new(); # Find the HereDocs in the existing code my $ExistingCodeHereDoc_ar=$Document_o->find(\&HereDocs) || [] +; for my $HereDoc_o (@$ExistingCodeHereDoc_ar) { #PPI::Dumper->new($HereDoc_o,whitespace=>0,locations=>1)-> +print; $Clipboard_o->Empty(); $Clipboard_o->Set(join('',$HereDoc_o->heredoc())); print join('',$HereDoc_o->heredoc())."\n"; { local $|=1; print STDOUT "Update the clipboard then 'Enter':"; <STDIN>; }; # See if the clipboard has been changed if ((my $NewText_s=$Clipboard_o->GetText()) ne join('',$He +reDoc_o->heredoc())) { print "Replaced with:\n$NewText_s\n\n"; chomp($NewText_s); push @NewHereDoc_a,PPI::Document->new(\( $HereDoc_o->content() ."\n" ."/* $Comment_S\n" # Comment .join('',$HereDoc_o->heredoc()) # ... origina +l commented out ."*/\n" # .$NewText_s # ... replace +ment ."\n" #.$HereDoc_o->terminator() # Prevents sp +urious terminator )); my $HereDoc_ar=$NewHereDoc_a[-1]->find(\&HereDocs) || +[]; #PPI::Dumper->new($HereDoc_ar->[0],whitespace=>1,locat +ions=>1)->print; #print join('',$HereDoc_ar->[0]->heredoc())."\n"; if ($HereDoc_o->insert_before($HereDoc_ar->[0])) { $HereDoc_o->delete(); } else { warn "insert_before failed!"; }; }; }; #PPI::Dumper->new($Document_o,whitespace=>0,locations=>1)->pri +nt; $Document_o->save($UpdatedCodeFilename_S) };

No doubt I'm doing something wrong --- but what?

Update The code as it currently stands behaves correctly and will find HereDocs and copy them to the clipboard so they can be pasted to an editor, edited then reclip to amend the HereDoc.


In reply to Problem with PPI HereDoc's by clueless newbie

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-03-28 11:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found