clueless newbie has asked for the wisdom of the Perl Monks concerning the following question:
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"
I'll getmy($query); $query =<<"ENDOFSQL"; Something ENDOFSQL $query = <<"ENDOFSQL"; Something ENDOFSQL
Note the doubling up of the terminators. Here is FindAndUpdateHeredoc scriptmy($query); $query =<<"ENDOFSQL"; /* # Just A Test Something */ else ENDOFSQLENDOFSQL $query = <<"ENDOFSQL"; /* # Just A Test Something */ else ENDOFSQLENDOFSQL
#!/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.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Problem with PPI HereDoc's
by Khen1950fx (Canon) on Nov 21, 2011 at 03:29 UTC | |
by clueless newbie (Curate) on Nov 21, 2011 at 12:13 UTC | |
Re: Problem with PPI HereDoc's
by Eliya (Vicar) on Nov 20, 2011 at 22:02 UTC | |
by clueless newbie (Curate) on Nov 21, 2011 at 01:06 UTC |
Back to
Seekers of Perl Wisdom