I want to ask the user multiple questions. I have two types of questions: Y/N or filename input. I\'m not sure how to place this all into a nice if
structure. And I
One word: Abstraction.
The solution you currently chose does not scale well, and contains too much repeated code. We will write a subroutine prompt
that hides much of the complexity from us:
sub prompt {
my ($query) = @_; # take a prompt string as argument
local $| = 1; # activate autoflush to immediately show the prompt
print $query;
chomp(my $answer = <STDIN>);
return $answer;
}
And now a promt_yn
that asks for confirmation:
sub prompt_yn {
my ($query) = @_;
my $answer = prompt("$query (Y/N): ");
return lc($answer) eq 'y';
}
We can now write your code in a way that actually works:
if (prompt_yn("Do you want to import a list")){
my $list1 = prompt("Give the name of the first list file:\n");
if (prompt_yn("Do you want to import another gene list file")){
my $list2 = prompt("Give the name of the second list file:\n");
# if (prompt_yn("Do you want to import another gene list file")){
# ...
}
}
Oh, so it seems you actually want a while
loop:
if (prompt_yn("Do you want to import a list")){
my @list = prompt("Give the name of the first list file:\n");
while (prompt_yn("Do you want to import another gene list file")){
push @list, prompt("Give the name of the next list file:\n");
}
...; # do something with @list
}
The @list
is an array. We can append elements via push
.
You can use Sub Routines. This helps you visibly and logically keep everything in-line. for instance
&main();
sub main {
print "Do you want to import a list(Y/N)";
my $input = ;
chomp $input;
if($input =~ m/^[Y]$/i) {
&importfile();
} elsif ($input =~ m/^[N]$/i) {
print "you said no";
} else {
print "Invalid option";
}
}
sub importfile
{
print "file name please ";
my $file = STDIN;
# import and process the file here.....
&main();
}
So you can import at many files this way.
A while ago I end up with following:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
if (&prompt_yn("CONTINUE")){
my @res = split(" ",&prompt("ENTER INPUT")) ;
print Dumper @res;
}
else{
print "EXIT\n";
}
sub prompt_yn{
my ($query) = @_;
$query = $query . " (Y/N): ";
print "$query";
while (<>) {
$_ =~ s/^\s+|\s+$//g;
$_ =~ s/\r|\n//g;
if ($_ =~ /\S/){
if ($_ =~ /^y$|^yes$/i){
# if you want information message about entered value uncomment this
# print "You have entered Y\n";
return 1;
}
elsif ($_ =~ /^n$|^no$/i){
# if you want information message about entered value uncomment this
# print "You have entered N\n";
return 0;
}
else{
# if you want information message about entered value uncomment this
# print "You have entered wrong value try again: \n";
}
}
print "$query";
}
}
sub prompt{
my ($query) = @_;
$query = $query . ": ";
print "$query";
while (<>) {
$_ =~ s/^\s+|\s+$//g;
$_ =~ s/\r|\n//g;
if ($_ =~ /\S/){
return $_;
}
print "$query";
}
}
Compared to previous solutions this handles empty inputs.