#!/usr/bin/env perl use strict; use warnings; my %companies; #big hash to hold all companies' information my %tasks; #hash to store task subroutines #main menu generation sub print_menu{ print "Please select one of the following seven options:\n\n"; print "1) Add a new company.\n"; print "2) Enter a company location.\n"; print "3) Enter a president's name.\n"; print "4) Add a board member.\n"; print "5) Remove a board member.\n"; print "6) Fill out template.\n"; print "7) Exit.\n"; } #obtain the user's menu choice, and verify its validity sub get_menu_choice { chomp (my $choice = ); until ($choice =~ /^[1-7]$/){ print "That was not a valid choice. Please enter a number 1 - 7:\n"; chomp ($choice = ); } return $choice; } #create a new company sub new_company{ print "Please enter the name of the new company\n"; chomp (my $company = ); if (exists $companies{$company}){ print "$company already exists, sorry\n"; } else { #set new company to a new hashref with the NAME attribute set #also set the board key to a blank hashref, to avoid warnings in add/remove #board member functions $companies{$company} = { NAME=>$company, board=>{} }; print "$company added, thank you.\n"; } } #prompt the user for the city and state, and set them in the appropriate company sub location{ my $company = get_company(); if (!defined($company)){ print "Sorry, no such company exists\n"; return; } print "In what city is $company located?\n"; chomp (my $city = ); print "And in what state is $company located?\n"; chomp (my $state = ); @{$companies{$company}}{qw/CITY STATE/} = ($city, $state); print "${company}'s location updated. Thank you.\n"; } #set the company's president sub president{ my $company = get_company(); if (!defined($company)){ print "Sorry, no such company exists\n"; return; } print "What is the name of the president of $company?\n"; chomp (my $pres = ); $companies{$company}{PRESIDENT} = $pres; print "${company}'s president updated. Thank you.\n"; } #The board members are a hash where the key is the member's name # and the value is 1. This makes deleting and checking for existance # very easy. sub add_board{ my $company = get_company(); if (!defined($company)){ print "Sorry, no such company exists\n"; return; } print "Enter the name of the new board member:\n"; chomp (my $member = ); if (exists ($companies{$company}{board}{$member})){ print "Sorry, $member is already a member of ${company}'s board\n"; } else { $companies{$company}{board}{$member} = 1; print "$member added to ${company}'s board. Thank you.\n"; } } #Remove a board member, simply using the delete() function sub remove_board{ my $company = get_company(); if (!defined($company)){ print "Sorry, no such company exists\n"; return; } print "${company}'s current board members: "; print join (', ', keys %{$companies{$company}{board}}), "\n"; print "Enter the name of the board member to remove:\n"; chomp (my $member = ); if (!exists($companies{$company}{board}{$member})){ print "$member is not a member of ${company}'s board!\n"; } else { delete $companies{$company}{board}{$member}; print "$member removed from ${company}'s board. Thank you.\n"; } } #open a template file and fill it out. sub template { my $company = get_company(); if (!defined($company)){ print "Sorry, no such company exists\n"; return; } print "Please enter the template file name:\n"; chomp (my $template = ); unless (-e $template and -f _ and -r _){ print "$template either doesn't exist, isn't a file, or isn't readble. Sorry.\n"; return; } open my $ifh, '<', $template or (warn "Could not open $template for reading: $!\n" and return); open my $ofh, '>', "$company.txt" or (warn "Could not open $company.txt for writing: $!\n" and return); while (<$ifh>){ #search for all template place holders, and replace as needed #replace the [BOARD] placeholder - /e evaluates replacement as code s/\[BOARD]/join(', ', keys %{$companies{$company}{board}})/ge; #replace all remaining placeholders s/\[([A-Z]+)]/$companies{$company}{$1}/g; #search for all 'Rensselaer' and 'Rensselaer University', and replace with RPI s/Rensselaer University/RPI/gi; s/Rensselaer(?! Polytechnic Institute)/RPI/gi; #print to output file. print $ofh $_; } close $ifh or (warn "Could not close input FH: $!\n" and return); close $ofh or (warn "Could not close output FH: $!\n" and return); print "$company.txt created from $template. Thank you.\n"; } sub the_end { print "Thank you for using this system. Good day.\n"; exit(); } #function to simply obtain a company name from the user #the other subroutines will call this one. sub get_company { print "Please select one of the following companies:\n"; print join (', ', keys %companies), "\n"; chomp (my $company = ); exists $companies{$company} ? $company : undef; } #this is known as a "dispatch table". It enables us to call the #correct subroutine, without a huge series of if/else blocks %tasks = ( 1 => \&new_company, 2 => \&location, 3 => \&president, 4 => \&add_board, 5 => \&remove_board, 6 => \&template, 7 => \&the_end, ); #here's our menu loop while (1){ print_menu; my $choice = get_menu_choice; $tasks{$choice}->(); }