http://qs1969.pair.com?node_id=545414

To save myself some typing I have written a small script to make the creation of new Perl scripts simpler. I called it newscript (it does what it says on the tin) and you run it with an argument of the script name you want to create. It checks that the file does not already exist then creates a new file with execute permissions and places

#!/usr/bin/perl # use strict; use warnings;

at the top so I have no excuse for not using strict and warnings. It then asks the user if they would like to start editing the new file; the script sets up a timeout for the user to answer so that it doesn't sit there waiting forever. The editor I prefer to use is nedit but you could substitute your favourite in $editor. If your preference is something like vi then you could start an xterm with vi as it's command to run. This is rather *nix-centric but that's mostly what I use. Here's the script. I hope that it is of interest.

#!/usr/bin/perl # use strict; use warnings; # Get modules, set autoflush on STDOUT. # use IO::File; use Term::ReadKey; STDOUT->autoflush(1); # Get name of script we want to create, die if it already # exists. # my $newfile = shift or die "Usage: newscript <filename>\n"; die "newscript: $newfile already exists\n" if -e $newfile or -l $newfile; # Make new IO::File handle to create script file with execute # permissions, die on failure. # my $scriptFH = IO::File->new($newfile, O_WRONLY|O_CREAT|O_TRUNC, 0755); die "newscript: open: $!\n" unless $scriptFH; # Set up hash-bang line and strictures for top of script, write # them to the new file and then close. # my $hashBang = "#!/usr/bin/perl\n#\n\nuse strict;\nuse warnings;\n\n"; $scriptFH->print($hashBang); $scriptFH->close(); # Set up editor command, prompts asking user if they want to # edit the new script, and a time-out value of five seconds. # my $editor = "/usr/local/bin/nedit"; our $prompt1 = "Start editing $newfile? ("; our $prompt2 = ") (y/n) : "; our $timeOut = 5; # Set up subroutine reference that will be used as the handler # for $SIG{ALRM}. # our $rcCountdown = sub { # If there is still time left, print prompt (decrementing # time-out value) and set alarm for one second. # if($timeOut) { print "\r", $prompt1, $timeOut --, $prompt2; alarm(1); } # Time is up, restore read mode and die. # else { ReadMode(0); die "Timed out\n" } }; # Install handler, call handler for the first time to prompt # and set alarm. # $SIG{ALRM} = $rcCountdown; $rcCountdown->(); # Set read mode to raw and await a key press. # ReadMode(4); my $resp = ReadKey(0); # If we got here we got a key press, reset read mode, unset # alarm and print a newline to move off prompt. # ReadMode(0); alarm(0); print "\n"; # If key pressed was 'y' then start the editor in the # background via exec, new editor window will appear and # shell will prompt for next command. # if($resp =~ /^y$/i) { exec "$editor $newfile &" or die "Couldn't invoke $editor: $!\n"; } # User doesn't want to edit so just exit. # exit;

Cheers,

JohnGG

Replies are listed 'Best First'.
Re: Create and edit new scripts
by graff (Chancellor) on Apr 25, 2006 at 01:11 UTC
    It might be easier if you just have a "template.pl" file, copy that to the requested file name for a new script, and provide a command-line option for the user to indicate whether to fire up an editor on the new file. By using a command-line option (e.g. "-e" to start the editor), the code becomes a lot shorter and easier to read (no need for ALRM handling, reading from term, etc), and a lot easier to use.

    And why not make the initial template something like this:

    #!/usr/bin/perl =head1 NAME =head1 SYNOPSIS =head1 DESCRIPTION =head1 AUTHOR =cut use strict; use warnings;
    That will make it clear that some amount of documentation should be included, which is usually a very good idea. (You can use the given file name and the user's name to initialize the first and last POD fields -- that would be very handy!)
      Your suggestions make a lot of sense. Documentation is a very good thing that I'm not very good at. I will have to get to grips with POD but it's something I have been putting off.

      The use of a command-line option would indeed make things easier but I wanted to use ALRM handling just to learn how to do it. I wrote this some years ago and the first cut of the ALRM stuff was pretty crude. I tweaked it more recently with the countdown, again because I thought it would be interesting to learn. I'm not sure about your "... and a lot easier to use." There's not a lot of difference between

      % newscript -e fred

      and

      % newscript fred ... prompt ... y

      Thank you for the feedback,

      JohnGG

        Your suggestions make a lot of sense. Documentation is a very good thing that I'm not very good at. I will have to get to grips with POD but it's something I have been putting off.</blocckquote>

        I know this is mere proselytism, anyway in case you don't really get into POD you could give ROBODoc a try. It has a couple of advantages:

        • It sucks up much less space than POD;
        • It mixes up fine with code and comments (you can easily make documentation from your comments);
        • It works with any language I know of, so you can ROBODoc your Java, your html, your C and your PHP too.
        • ROBODoc can build a one-document digest from a whole code tree;
        • You can anyway generate HTML, RTF, PDF... from ROBODoc as well as POD;
        • Last, you can also generate POD with the ROBODoc to Pod translator script.
Re: Create and edit new scripts
by teamster_jr (Curate) on May 05, 2006 at 10:11 UTC
    I know i'm late to this party, but i have this in my .vimrc:
    function! New_Plugin(x) let mfile=a:x let packname=substitute(a:x, ".pm$","","") if a:x !~ '\.pm$' let mfile=mfile.".pm" endif execute ':e Plugins/' . mfile :r files/stub.pm :0d execute "%s/STUB/" .substitute(packname, "/", "::", "g") endfunction
    This takes a stub file and copies it into a plugins directory (for use with Module::Pluggable), renames the package line and opens it for editing (it also works with subpackages). I also have this:
    function! New_Template(x) let mfile = a:x if a:x !~ '\.tt$' let mfile = mfile . ".tt" endif execute ':e Templates/' . mfile endfunction
    For template toolkit templates (it doesn't use a stub, but will create a tt template in the correct place).
    a
Re: Create and edit new scripts
by blazar (Canon) on Apr 26, 2006 at 10:17 UTC
    The editor I prefer to use is nedit but you could substitute your favourite in $editor.

    How 'bout having it use $ENV{EDITOR}, if defined?

      I did originally use $ENV{EDITOR} but cut it out for the OP to make things simpler. I also cut out some command-line flags that gave to option to create Bourne, Korn or Bash scripts, also for simplicity. I would add those back in but in a different way now that I have seen the various replies.

      Sorry it took a long time to notice your reply. I need to find out how to get automatic notification when there is a reply to one of my posts. There is probably an option I haven't found yet.

      Cheers,

      JohnGG

        Sorry it took a long time to notice your reply. I need to find out how to get automatic notification when there is a reply to one of my posts. There is probably an option I haven't found yet.

        It's the chatterbox nodelet. If you don't like the CB, turn it off with /chatteroff (exactly like I did!), you will still see the messages directly addressed to you, including the notifications. Of course if you had it, then I'd have /msg'd you instead of writing a reply.

Re: Create and edit new scripts
by jasonk (Parson) on Apr 25, 2006 at 04:26 UTC
    Module::Start? Although I'm not really a fan of anything that inherits from Spiffy...

    We're not surrounded, we're in a target-rich environment!
      All the modules I have written so far (not that many) have been hand-rolled. Thank you for your suggestion, I will investigate.

      Cheers,

      JohnGG

Re: Create and edit new scripts
by arkturuz (Curate) on Apr 25, 2006 at 07:55 UTC
    I create a new perl program in nedit like this:
    set_language_mode("Perl") insert_string("#!/usr/bin/perl -w") newline() newline() insert_string("use strict;") newline() newline()

    It is simple to add an input form to ask for a file name, but I don't need it.

      I use nedit too and a very similar macro (bind to ctrl+shift+P :) However may I suggest that you'd better use
      use warnings;
      rather than
      #!/usr/bin/perl -w
      which has the undesirable side-effect to enable warnings in modules you use, and some really can't stand it (CGI.pm for instance).
      BTW here's my macro, which uses "which" to determine the path to perl :
      set_language_mode( "Perl" ) myperl=shell_command( "which perl" , "" ) insert_string("#!" myperl "\n\nuse strict;\nuse warnings;\n") set_cursor_pos(100)
        I have the same binding :-)

        Thanx for the suggestion!
        I use '-w' because I want all the warnings in most of the programs I write. Some of them are CGI apps, and I like them to run clearly.

      I don't know whether you have had this issue with nedit. If I create a new script from within the editor and save it without closing the edit session and then chmod +x it in the shell I can run it. If I make further changes to the script and save them I can no longer run the script as the permissions revert to rw-r--r-- after the save. If I create the file outside of nedit with execute permissions and then start editing, nedit doesn't trample on the permissions during the edit/save/test/edit ... cycle. This was one of the reasons for writing "newscript".

      Thank you for your reply, it has given me useful pointers to how I can better use nedit.

      Cheers,

      JohnGG

        I hadn't have this problem. It works OK for me on Linux system.
        Although, when I run the program from nedit I run it with (binded to Ctrl+Shift+E):
        chmod +x %; %
        '%' stands for current editing file.
Re: Create and edit new scripts
by zentara (Archbishop) on Apr 25, 2006 at 11:49 UTC
    Just for the sake of discussion, I do this with mc(Midnight Commander) by editing it's cedit.menu file to make templates. I have a bash alias 't' which creates an empty file, like "t myscript", then I hit F4 on myscript to open it in mc's internal editor, at which time if I hit F11, I get a menu of keys "g thru t" to let me select a template to insert. 'p' is just your simple template, but 'g' gives me a Gtk2 template with a full Mainloop and a few empty boxes to fill in, and a pre-made exit button". While 't' gives me a basic Tk window.

    I'm not really a human, but I play one on earth. flash japh
      I can see how a collection of template files such as you describe would save an awful lot of typing or, more likely, a lot of cut & paste errors. I imagine it would be possible to set up something similar with nedit macros and I will test this out.

      Thank you for your ideas.

      JohnGG