Hi Edward!
On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya <[EMAIL PROTECTED]> wrote: > Hi, > Why my code below fail to open and > print the file contents > > when I do: > > perl mycode.pl -f filename > > Regards, > Edward WIJAYA > SINGAPORE > > __BEGIN__ > use strict; > use warnings; Good Start! Those pragmas above are very helpful! > > use Getopt::Std; > use vars qw($f); The above is good, but is now obsolete. The preferred method is to use 'our' declarations Also, the 'getopts()' function creates variables of the form 'opt_*' where '*' is replaced with your option name. So, for example, you should have declared opt_f here: our $opt_f; > getopts('f:'); > > my $f = $ARGV[0]; > open ( INFILE, '<', $f) > or die "$0 : failed to open input file $f : $!\n"; This is good, I especially like the 'die' statement in case it fails. Good Job! It is relevant to note that opening a file to read is default, so the '<' was not necessary. However, it is nice to make it obvious which way you are opening the file (read only, write, or etc.). I might have written this as follows: open INFILE, "<$opt_f" or die "$0: failed to open input file $opt_f: $!"; > close ( INFILE ); > Why are you closing the file you just opened? Maybe it's because you don't understand the diamond ('<>') operator. The diamond operator will read the end of you command line and open each filename it finds there for processing. It allows you to write a Perl script that acts like any other UNIX process (e.g. cat, grep, etc ... ). In your code example, it appears as if you are trying NOT to use the diamond operator and force your user to input a single filename with the '-f' option. If this is the case, you don't want to close your 'INFILE' above until after you've used it! Like this: while( <INFILE> ) { print; } > while ( <> ) > { > print $_; Inside this block, the '$_' variable is default and will be assigned the next line from the file that 'while' is processing. Because it is default, it is not necessary. > } > __END__ > > -- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > Edward, I could write this script two ways. The first is the way I prefer and it doesn't use 'Getopt::Std' at all: #!/usr/bin/perl use warnings; use strict; while( <> ) { print; } That code above uses the diamond operator correctly. The diamond ('<>') operator reads the command line and processes each file name on the command line after your command! So, in a command called 'perl_cat.pl' with a command line like: # perl_cat.pl foo.txt bar.txt The diamond operator will first open foo.txt (processed in the while loop) and print each line, then, open bar.txt and print each of it's lines! However, if you are really trying to use the 'Getopt::Std' module, I'd do it like this: #!/usr/bin/perl use warnings; use strict; our $opt_f; getopts( 'f:' ); open INFILE, "<$opt_f" or die "$0: Can't open file $opt_f: $!"; while( <INFILE> ) { print; } In the above code, unlike yours, I don't 'close' INFILE. That's because Perl will close it for me at the end of my code. I hope this helps! --Errin -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>