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

Perl Script to write a perl script

by electroman00 (Novice)
on Dec 02, 2009 at 19:54 UTC ( #810663=perlquestion: print w/replies, xml ) Need Help??
electroman00 has asked for the wisdom of the Perl Monks concerning the following question:

Hi all..... Trying to write a perl script that will write a perl script while only substuting some of the vars. ===== Here's my test prog
#!/usr/bin/perl # External Modules #use strict; #use warnings; use Cwd; system "clear"; $cwdir = cwd; $APPNAME="AnyName"; # << "AnyName" must substitute in prog_file below. #require "$cwdir/prog_file"; open(PROGFILE, "<$cwdir/prog_file"); # open for input #my(@lines) = <PROGFILE>; # read file into list @lines = <PROGFILE>; # read file into list #my($line); foreach $line (@lines) # loop thru list { print "$line"; } close(PROGFILE);
===== Here's the file prog_file
#!/usr/bin/perl # Sample Program \$APPNAME="AnyName"; print "This is the var \$APPNAME and this is what needs to get substit +uted $APPNAME\n";
The output needs to be the prog_file with only the second $APPNAME in the print line substituted by the var in the So the output looks like this....
#!/usr/bin/perl # Sample Program print "This is the var $APPNAME and this is what needs to get substitu +ted AnyName\n";
It somewhat works but not exactly, seems to be a catch 22 built in here. Thanks for any and all help in advance...

Replies are listed 'Best First'.
Re: Perl Script to write a perl script
by almut (Canon) on Dec 02, 2009 at 20:30 UTC

    One way would be to read the file into a string, put qq (with a delimiter that doesn't occur in the file) around it, and eval it

    $APPNAME = "AnyName"; open my $fh, "<", "prog_file" or die $!; my $lines; { local $/ = undef; $lines = <$fh>; } print eval "qq|$lines|";

    Another way would be to put $lines = qq| ... |; around the entire content of the file (in the file itself), and then use do

    $APPNAME = "AnyName"; do "prog_file"; print $lines;

    A third way would be to use regex substitution to replace strings like $APPNAME in the lines, but only if unescaped...

    But maybe what you're really looking for is a templating system, like Text::Template, the Template Toolkit, etc...

Re: Perl Script to write a perl script
by Limbic~Region (Chancellor) on Dec 03, 2009 at 03:12 UTC
    Everyone has suggested using some form of templating and I agree. I also know that sometimes learning method X when what I want to do is Y can be frustrating. Here is an example using HTML::Template - When should I use a dispatch table?. It isn't particularly good but it shows how easy it is and was one I remembered off the top of my head. Don't get frustrated, take things 1 step at a time.

    Cheers - L~R

      First, thanks for the responses. After posting this I did do further research and found HTML::Template. Not sure it's what I'm looking for though. The code I provided was an example of the task at hand. Basically, it's to take a perl script and treat it as a flat text file and read it in substituting the vars as needed from the perl script creator. I do have a working bash script that was very easy to make.
      #!/bin/bash APPNAME="AnyApp" screen=1 if [! screen ]; then { cat > /tmp/new_prog_file << EOF } else { cat << EOF } print "This is the var \$APPNAME and this is what needs to get substit +uted $APPNAME\n"; EOF
      Works a treat with little effort (max efficiency) the goal. However perl seems to be a cronic complainer. It seems from tests so far the only way to get perl to sub the vars is to make prog_files an include, then perl complains about everything in prog_files. As a note.... \$APPNAME results in $APPNAME.... $APPNAME results in AnyApp.... Bash just eats, digests and spits out the result. Simple, my favorite method KISS. Now I also tried the equiv in perl....
      #!/usr/bin/perl $APPNAME="AnyApp" require "prog_file.lib"; read_prog
      sub read_prog print <<"EOF"; print "This is the var \$APPNAME and this is what needs to get substit +uted $APPNAME\n"; EOF 1;
      The problem is getting an "if" to print to screen or to a file to work, either from the require sub or from the perl creator prog. Easy using bash, not so with least not for me. My mind is already boggled by the var substitutions that needed to be done throughout. Solved the var boggle issue using a var naming convention. Thanks in advance...
      Thanks for the advice, however the server that is going to be running the prog doesn't have, nor will it have the mods loaded by default. So it kinda rules out using the mod, at least for now.
Re: Perl Script to write a perl script
by ikegami (Pope) on Dec 02, 2009 at 22:29 UTC
    To properly process your template by your specs, you'd need to parse Perl. That's no small task. Don't reinvent the wheel. Use Template-Toolkit or something.
Re: Perl Script to write a perl script
by leocharre (Priest) on Dec 02, 2009 at 20:49 UTC

    Yes, I have a suggestion, stop doing this. Instead, use a vim template for new files...


    :insert #!/usr/bin/perl use strict; use vars qw($VERSION); use LEOCHARRE::CLI2 ':all'; use LEOCHARRE::Dir ':all'; $VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)/g; exit; sub usage { qq{$0 [OPTION].. -d debug -h help -v version }} __END__ =pod =head1 NAME =head1 DESCRIPTION =head1 OPTIONS =head1 USAGE =head2 Usage Examples =head1 AUTHOR Leo Charre leocharre at cpan dot org =head1 SEE ALSO =head1 LICENSE This package is free software; you can redistribute it and/or modify i +t under the same terms as Perl itself, i.e., under the terms of the " +Artistic License" or the "GNU General Public License". =head1 DISCLAIMER This package is distributed in the hope that it will be useful, but WI +THOUT ANY WARRANTY; without even the implied warranty of MERCHANTABIL +ITY or FITNESS FOR A PARTICULAR PURPOSE. See the "GNU General Public License" for more details. =cut .

    In your ~/.vimrc

    autocmd bufnewfile *.pl so ~/

    Now, whenever you run a command like # vim , that template will show up. If you place APPNAME where you want it, you can can then do a search and replace such as :%s/APPNAME/blabla/g

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://810663]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2018-06-18 08:36 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (109 votes). Check out past polls.