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

You could use a dispatch table:

my %filetype = ( 'c' => \&create_c, 'bash' => \&create_bash, 'perl' => \&create_perl_script, 'pl' => \&create_perl_script, 'pm' => \&create_perl_module, ); sub create_c { my $filename = shift; # stuff for creating a c file } sub create_bash { my $filename = shift; # stuff for creating a bash script } ... print "What kind of file do you want to create?\n"; printf "Supported file types: %s\n", join ', ', sort keys %filetype; # ask user for desired filetype -> $type # ask user for desired filename -> $name if (exists $filetype{$type}) { # this calls the function that is stored in the hash # e.g. create_bash($filename) $filetype{$type}->($name); } else { die "Sorry, file type '$type' is not supported.\n"; }

If you want to support some other filetype (e.g. SQL) at some point then you only need to write a new function 'create_sql' and update the %filetype hash.

Replies are listed 'Best First'.
Re^2: RFC: newscript.pl , my very first script!
by Darfoune (Novice) on Jul 30, 2015 at 19:01 UTC

    Hello Monk::Thomas

    Your idea is brilliant, it will make newscript much clearer and easier to maintain!

    Although, right now I'm working on an interactive clustering facility, a way to regroupe modules or libraries under tags, or clusters.

    It's still a stand-alone program, I haven't added it to newscript yet and once I get it implemented I will work on a way to make, remove and choose cluster from the command line directly

    It's operating on a file, .cluster, created in the user's $HOME directory. Although a little cryptic to read, it's possible to edit the file directly to add, remove and edit cluster as long as the ;name;modules, syntax is followed (both semi colons arround name and trailing coma after every module is important). As of right now, it's not possible to edit interactively an already made cluster. At the moment, only perl module can be clustered.

    It's a work in progress but if you want, have a try and tell me what you think of it ;)

    As of the many "why the hell did he do it this way oO " that you gonna ask yourself.. well I did with what I knew :P.

    Thanks for you feedback ! :)

    #!/usr/bin/perl use warnings; use strict; my ($cmd,$usercmd); my $cfile_content = ''; my $command = 1; my $home = $ENV{HOME}; chomp ( my $cfile = "$home/.cluster") ; my ( @namelist, @modname); my %nammod; my $timedone = 0; my $doneit = 0; my $tempfile = "/$home/tmp_cluster"; # Greetings print "\n\n\t\t\tWelcome to the Cluster Facility\n"; _filecheck(); _cluster_help(); # We need some vars that are setup in this sub _make_list(); _input(); # Get command from user sub _input { print "\n\nCommand -> "; chomp ($usercmd = <STDIN>); _ineed($usercmd); } # Main menu sub _ineed { $cmd = shift ; # Make a list of registered cluster if ($cmd =~ /list/i) { _thelist(); _input(); } # Add a new cluster to /$home/.cluster elsif ($cmd =~ /add/i) { _add(); _input(); } # Remove a cluster from /$home/.cluster elsif ($cmd =~ /remove/i ) { _removec(); _input(); } # Edit a cluster using it's name elsif ($cmd =~ /edit/i) { # _edit(); print "\n\n\nNot Available Yet\n\n\n"; _input(); } # Call the usage sub elsif ($cmd =~ /help/i ) { _cluster_help(); _input(); } # Exit the program elsif ($cmd =~ /(exit|quit)/i ) { exit; } # Else you're lost, print usage for you else { print "\n\n//Invalid command; Take a look a this:\n"; _cluster_help(); _input(); } } # to add a cluster: sub _add { # call on _filecheck to verify if /$home/.cluster exist # skip if we've done the check once already. my $addclus = 1; print "\n\n\t\t\t\tAdd a Cluster:\n"; while ($addclus) { my @cmodules; # Get cluster name from user print "\t\tFor a list of registered cluster use 'list',\n"; print "\t\t'return' to get back to main menu, 'exit' to leave. +\n\n\n"; print "\nName of your new cluster: "; chomp (my $cname = <STDIN>); # Test the input, return 2 if everything is good # return 1 if a test fails, return 3 if 'list' was input my $checkres = input_check($cname); print "\$checkres is $checkres\n\n"; if ($checkres == 1) { print "//problem inside input_check\n\n"; redo; } elsif ($checkres == 3) { redo; } # check for duplicates for my $uname (@namelist) { return _add() unless ($uname !~ m/\Q$cname/); } print "Which module you want in the $cname cluster?:\n"; # get modules from user print "Module name: "; while (<>) { if ($_ =~ /done/i) { last; } else { my $modcopy = $_; my $test = input_check($modcopy); if ($test == 2) { push @cmodules, $_; } elsif (($test == 1) || ($test == 3)) { print "Module name: "; next; } } print "Module name: "; } # write cluster name; followed by each modules, to /$home/.clu +ster open (my $CLUS, '>>', $cfile); print $CLUS ";$cname;"; for my $mods (@cmodules) { chomp $mods; # append a coma after each module print $CLUS "$mods,"; } close $CLUS; # ask user for more cluster, if no call _input(); print "\nAdd another cluster? [yes/no]: "; chomp (my $answer = <STDIN>); if ($answer =~ /yes|y/) { @cmodules = undef; redo; } else { # if answer is no, we're done here $addclus--; } } } # Used to modify existing cluster entry. # Not sure how to edit modules of a given cluster yet. #sub _edit { # my $editit = 1; # while ($editit) { # print "\n\nWhich Cluster would you like to modify?: "; # chomp (my $modify = <STDIN>); # if ($modify =~ /return/i) { # print "\nBack to main menu.\n"; # return _input(); # } elsif ($modify =~ /list/i) { # _thelist(); # } # for my $name (@namelist) { # if ($name =~ m/\Q$modify/) { # print "\nWe editing -> $modify\n"; # print "Name of Cluster: $name. Modules of $name: $namm +od{$name}\n\n"; # # } # } # print "Edit other Clusters? [yes/no]: "; # chomp (my $yesno = <STDIN>); # if ($yesno =~ /yes|y/i) { # redo; # } else { # $editit--; # } # } #} # Used to remove whole existing clusters. sub _removec { my $keepgoing = 1; while ($keepgoing == 1) { my $chkinhash; my $newcfile = ''; # Print a list of Clusters _thelist(); print "Cluster to remove: "; # Ask user which Cluster he wishes removed chomp (my $remclus = <STDIN>); my $testres = input_check($remclus); if ($testres == 1) { print "Syntax error\n"; redo; } elsif ($testres == 2){ } elsif ($testres == 3){ redo; } # Checks if the input name matches one from namelist for my $name (@namelist) { # If yes print a warning if ($name =~ m/\Q$remclus/) { print "\$name is \$remclus: $name == $remclus\n"; $chkinhash = $nammod{$remclus}; print "\$chkinhash is: $chkinhash\n"; # If it doesn't match, append it to $newcfile to rebui +ld cfile } else { if ($newcfile) { $newcfile = "$newcfile;$name;$nammod{$name}"; } else { $newcfile = ";$name;$nammod{$name}"; } } } print "\n\n\$newcfile is $newcfile\n\n"; unlink "$cfile"; open (my $NCLUS, '>', $cfile); print $NCLUS "$newcfile"; close $NCLUS; $keepgoing--; } } # This is done once every time the program run sub _filecheck { # check if .cluster file exist if (-e $cfile) { # If it does, make sure it's a file and not something wierd if (-f $cfile) { # Check if you have read and write permission if (-r -w $cfile) { # you are all good print "All checks are good\n"; # We don't wanna redo these test. # $doneit++; # Make a list of cluster name # return _make_list(); } else { # if you can't read or write cfile, we've got a p +roblem print "You can't read nor write $cfile\n"; exit; } } else { # if cfile isn't a plain file, we've got a problem print "$cfile is not a plain file\n"; exit; } } else { # if file doesn't exist, print a warning and continue print "$cfile doesn't exist\n"; } } # Make a hash to map cluster names to their modules sub _make_list { # Read in $home/.cluster file open (my $CLUS, '<', $cfile); while (<$CLUS>) { chomp; # If .cluster is single lined, assign $_ to it if ($cfile_content eq '') { $cfile_content = $_; # If .cluster is multi lined, apend $_ to clusterfile_content + } else { $cfile_content = "$cfile_content$_"; } } close $CLUS; # use ';' to separate cluster names and modules. Put the result in + array my @splitted_file = split /;/, $cfile_content; # Discard the first entry, not sure where it gets the whitespace shift @splitted_file; # set up the hash. Keys are the names, values the modules %nammod = @splitted_file; # Assign keys and value to their respective array for later use @modname = values %nammod; @namelist = keys %nammod; # unset variables to get a new list everytime $cfile_content = ''; $timedone++ } sub _thelist { _make_list(); print "\n\t\tThere's the list of registered Clusters:\n"; print "Cluster_Name => Modules, \n\n"; # sort Cluster by name and print for my $key (sort keys %nammod) { my $value = $nammod{$key}; print "$key => $value\n"; } print "\n\n"; } # Validates input sub input_check { chomp (my $totest = shift); # (2) Check for punctuation if ($totest =~ /^(\w)+(::(\w)+)*?[^[:punct:]]$/ ) { print "//(2); pass\n"; # Check if input match list if ($totest !~ /list/i) { print "//(3): pass\n"; # Check if input match return if ($totest !~ /return/i) { print "//(4): pass\n"; if ($totest !~ /exit|quit/i) { print "//(5): pass\n"; return(2); } else { # match exit or quit print "//(5): Failed: $totest: Leaving\n"; exit; } else { # match return print "//(4): Failed: $totest: Going back to main menu +\n"; _input(); } } else { # match list print "//(3): List\n"; _thelist(); return(3); } } else { # match punctuation print "\n//(2): Failed: Contain bad characters\n"; print "//No punctuation allowed\n\n"; return(1); } } sub _cluster_help { print<<EOF; Newscript.pl: Cluster Facility You can use this facility to group your most frenquently used modules. For exemple, you select Perl and a name, inet, then you can make a new cluster that contain your module +s: In this case only 2 modules LWP::* and CGI::*. Next time you create a newscript, you can use the following: newscript.pl [--cluster=inet] [name] and newscript will create a template with the apropriate language and your clustered modules. Options: -list Print a list of existing cluster and their conten +t. -add Add a new cluster. -remove Remove an existing cluster. -edit Remove a modules from within an existing cluster. -help Print this message. -exit Exit program. -quit Exit program. EOF }