slinky773 has asked for the wisdom of the Perl Monks concerning the following question:

OK, I have a problem. I was making a text editor completely in a command prompt (bad idea, I know) for practice in perl, mostly to get the feel of filehandles. I have come to a standstill here;
#!/usr/bin/perl -w use strict; use warnings; use Carp; if(open(FILE, "text.txt")) { print "Opened text.txt!\n"; print "Reading file...\n"; my @array = <FILE>; close FILE; print "File read!\n"; print "Current text in file:\n"; print "**************\n"; foreach my $lines (@array) { print "$lines\n"; } print "**************\n"; print "Edit file?Y/N\n"; print "If answer is no,\n"; print "then the program will\n"; print "be closed.\n"; my $input = <STDIN>; if($input =~ m/y/i) { print "Reopening file for\n"; print "editing...\n"; if(open(EDIT, ">text.txt")) { print "File sucessfuly opened\n"; print "for editing!\n"; if(<EDIT>) { print "File has data.\n"; print "Overwrite? Y/N\n"; print "If answer is no,\n"; print "program will be closed.\n"; my $moreInput = <STDIN>; if($moreInput =~ m/y/i) { print "Are you sure?\n"; my $evenMoreInput = <STDIN>; } elsif($moreInput =~ m/y/i) { print "OK, then!\n"; print "Closing program...\n"; exit 0; } } } else { confess "Something went wrong! $!"; } } elsif($input =~ m/n/i) { print "OK, then!\n"; print "Closing program...\n"; exit 0; } else { print "That is not a valid\n"; print "answer. Type your\n"; print "answer again.\n"; $input = <STDIN>; next SOMETHING; } } else { confess "Something went wrong! $!"; }
As you can see, I have tons of if else statements like this:
if($input =~ m/y/i) { #do something } elsif($input =~ m/n/i) { #do something else } else { #do something different }
Now, this creates a lot of cluster, and I normally would use a subroutine or something for this. However, I don't know subroutines well enough with using variables as parameters. Can you guys help me out? This kind of problem has been bothering me a lot with other instances. My biggest problem is that I don't know how to access variables passed as parameters under a specific name. I will be passing variables of different names to the subroutine, so I need some sort of way to access, for example, the first variable passed under a certain name, like how you access backreferences in regexes, You know, like $1 or $2 and so on. How can I do something like that in perl? I know that in Java you can do something like this:
import java.util.Scanner; public class Stuff { public static void main(String[] args) { Scanner somethingScan = new Scanner(System.in); int lotsOStuff = somethingScan.nextInt(); MoreStuff(lotsOStuff); } public static void MoreStuff(int something) { System.out.println(something); } }
Where you can call the first parameter passed a certain name. I just ran that, and it worked fine. I'm sure there is something like that for Perl, I just can't find it. Can someone help me here? EDIT: You may wonder why I'm not using Java instead of Perl for this then, but the answer is, Perl is much simpler then Java. In java, I can't simply say
my $input = <STDIN>
I have to say:
Scanner newScan = new Scanner(System.in); String input = newScan.nextLine();
which is a lot more stuff to type. Also, filehandles are just not as simple in java. I've taken a look, and I haven't actually used opening files in Java, but I've looked at code examples and it's just an ugly cluster of "import java.util.blahblahblah" and "blahblahblah.blahblahblah.blahblahblah" and all that. I hate that kind of stuff. So that is why I'm not using Java. EDIT: I just ran the program for the first time (lol, I know) and it stops at line 43, saying this:
youngs-mac-mini:Documents fenimore$ perl SomeStuff.pl Opened text.txt! Reading file... File read! Current text in file: ************** ************** Edit file?Y/N If answer is no, then the program will be closed. y Reopening file for editing... File sucessfuly opened for editing! Filehandle EDIT opened only for output at SomeStuff.pl line 43. youngs-mac-mini:Documents fenimore$
Er...

Replies are listed 'Best First'.
Re: Problems with Subroutines
by Juerd (Abbot) on Sep 01, 2011 at 00:12 UTC
    Beginning Perl has a chapter on subroutines; it's chapter 8 and it answers all your questions.

    The error you're getting is caused by trying to read from a filehandle that was opened for output only. You can't do that. Although it's possible to open a filehandle that you can both write to and read from, that's an advanced topic and not suited for beginners.

    Also, don't write to the file that you're still reading. Strange things will happen. Instead, write to a new file and rename that when you're done and sure that the old file may be removed. This also avoids some race conditions, and incomplete files if the program should crash before it's done writing.

Re: Problems with Subroutines
by ig (Vicar) on Sep 01, 2011 at 08:09 UTC

    You can also find answers to many of your questions in perlsub.