Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: RFC: newscript.pl , my very first script!

by 1nickt (Canon)
on Jul 24, 2015 at 22:03 UTC ( [id://1136238]=note: print w/replies, xml ) Need Help??


in reply to RFC: newscript.pl , my very first script!

You have an error in your code:

exec (`emacs -nw +50 $name`);

The backticks are already a system call, so you are nesting them by putting them inside a call to exec(). Try changing it to:

exec ("emacs -nw +50 $name");
The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: RFC: newscript.pl , my very first script!
by afoken (Chancellor) on Jul 25, 2015 at 19:14 UTC
    exec ("emacs -nw +50 $name");

    ... and finally, to avoid nasty surprises when $name contains characters that the default shell interprets instead of passing them unmodified to emacs, get rid of the shell. And check for errors, because exec could fail, like most other system calls.

    exec('emacs','-nw','+50',$name) or die "exec emacs failed: $!";

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      That's a very good point. Is it safer to make checks for everything the user can input or that has no influence in the security of the program?

      What I need to do:

      - add possibility for the user to cluster frequently used modules/libraries with tags (thinking about using hashes)

      - make use of environment variable to determine which is the default editor and make use of it, instead of assuming emacs. (not sure how to do that yet)

      thanks for your suggestions :)

        What I need to do:

        - add possibility for the user to cluster frequently used modules/libraries with tags (thinking about using hashes)

        A hash of hash references looks like a good idea. Use arrays in the third level to allow more than one library per tag:

        my %langTags=( perl => { HEAD => [ '#!/usr/bin/perl', ], DEFAULT => [ 'use strict;', 'use warnings;', ], cgi => [ 'use CGI::Carp qw( fatalsToBrowser );', 'use CGI qw( -nosticky -compile -no_debug -private_tempfil +es -newstyle_urls );', ], moose => [ 'use Moose;' ], # ... }, bash => { HEAD => [ '#!/bin/bash', ], cgi => [ 'source /usr/local/lib/bash/bashcgi-lib.bash', ], csv => [ 'source /usr/local/lib/bash/csv-lib.bash', ], ourlibs => [ 'source /usr/local/lib/bash/foo-lib.bash', 'source /usr/local/lib/bash/bar-lib.bash', ], # ... }, c => { DEFAULT => [ '#include <stdio.h>', '#include <stdlib.h>', '#include <string.h>', ], # ... }, # ... );

        Note that you could use pseudo-tags to define a file header, default libraries, and anything else that you may need.

        Think about getopt for entering tags. Use Getopt::Long.

        How should the command line look like?

        Language and libraries as two parameters with values
        newscript --lang=perl --use=cgi,moose,dbi foo.pl
        newscript --lang=bash --use=cgi,csv,ourlibs foo.bash
        Language as argument with value, one flag argument per library tag
        newscript --lang=perl --cgi --moose --dbi foo.pl
        newscript --lang=bash --cgi --csv --ourlibs foo.bash
        Language and libraries as flag arguments
        newscript --perl --cgi --moose --dbi foo.pl
        newscript --bash --cgi --csv --ourlibs foo.bash
        Implicit language, derived from output file name
        newscript --cgi --moose --dbi foo.pl
        newscript --cgi --csv --ourlibs foo.bash

        I prefer "don't make me think" and "don't make me type".

        Implicit language is not hard, just guess it from the file extension: .pl and .pm for Perl, .sh and .bash for bash, and so on. Without a file extension, require a language argument. Use a hash for default mappings:

        my %extToLang=( pl => 'perl', pm => 'perl', c => 'c', h => 'c', sh => 'bash', bash => 'bash', ); my $filename; my $lang; # setup $filename and perhaps also $lang if (!$lang and ($filename=~/\.([^.]+)$/) { $lang=$extToLang{$1}; } $lang or die "Missing language parameter";

        Library tags would be different for different languages, e.g. moose would make no sense for bash at all, so it should result in an error message. When you use Getopt::Long for the first form, you would check the library tags returned from GetOptions(). The language is known at this point, either from a --lang option, or from the file extension. When you use a flag argument for each library tag, you need to know all allowed tags before calling GetOptions(). For that, you have two options:

        • Determinate the language first, either from the filename extension or a first call to GetOptions() just to fetch the language argument value / language flag. Then build a list of legal library tag flag arguments, and call GetOptions() a second time to get a list of library tags.
        • Simply build a list of all allowed library tags for all languages, then call GetOptions() once. This sets the language (if not detected by the filename extension) and a list of library tags. Some of the tags may not be allowed for the selected language, so you have to check the list manually.

        Legal values for the language are simply available as keys %langTags. Legal values for the library tags are available as keys %{$langTags{$language}}. A little bit of code is required to get a list of all library tags:

        use List::MoreUtils qw ( uniq ); my @allTags=uniq map { keys %$_ } values %langTags;

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        What I need to do:

        - make use of environment variable to determine which is the default editor and make use of it, instead of assuming emacs. (not sure how to do that yet)

        Commonly, the EDITOR or VISUAL environment variables specify which editor executable to use. If both are unset or empty, use some arbitary fallback. The debian people use a bunch of symlinks to specify a default editor in /usr/bin/editor.

        The two environment variables may contain only the name, not the absolute path of the editor. So you also have to search $ENV{'PATH'}.

        Different editors have different command line options. The only thing that you can rely on is that the editor will accept a single argument containing a filename to be edited. In other words: no extra command line options as long as you allow having different editors.

        #!/usr/bin/perl use strict; use warnings; use List::Util qw( first ); sub exec_editor { my $filename=shift; my @path=split /:/,$ENV{'PATH'}; my $editor=first { length($_) && -f($_) && -x(_) } map { my $file=$_; /\// ? $file : map { "$_/$file" } @path } ( $ENV{'EDITOR'}//'', $ENV{'VISUAL'}//'', '/usr/bin/editor', # for Debian and friends qw( joe emacs nano vi ), ); defined($editor) or die "Can't find an editor"; exec($editor,$filename) or die "Can't execute $editor: $!"; } @ARGV==1 or die "Usage: $0 file-to-edit\n"; exec_editor($ARGV[0]);

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Well thank you very much, you guys really know what you're doing. That's definitely something I look forward writing.

        Now I first have to go again over map and make sure I get it right, I'll have to try getops as well since I haven't yet, and I just started this morning the chapter on references in intermediate perl so hopefully soon enough I'll rewrite newscript with your suggestions in. I'll keep you updated, thanks! :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1136238]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2024-04-18 09:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found