Basic File Input/Output and Subroutines

#!/usr/bin/perl -w
######################  Elementary File I/O  ############################

die "Usage: $0 infile outfile\n" if @ARGV != 2;
open(INFILE, "$ARGV[0]")  || die "Cannot open $ARGV[0] for reading.\n";
open(OUTFILE,">$ARGV[1]") || die "Cannot open $ARGV[1] for writing.\n";

@lines = <INFILE>;  ####  Reads the whole file in ONE read!
                    ####  Each element of @lines is one \n-terminated line.
#####  Above is the same as:
#####  push(@lines, $_) while <INFILE>;
foreach $line (@lines)
{
     print OUTFILE $line if $line =~ m/#/;
}

close(INFILE);
#########  No, I don't need to close OUTFILE first before reopen!!
open(OUTFILE, "$ARGV[1]") || die "Cannot reopen for $ARGV[1] for reading.\n";    
print while (<OUTFILE>);  #####  Idiomatic usage of $_ default!!
close(OUTFILE);

#############  Function Parameters of Scalar and List Type  ################

@list = ("foo","bar","snafu","ouch","oops");
$oneline = run_together(@list);
print "\n$oneline\n";

@address_parts = ("John Doe", "123 Main Street", "Nowhere, CA 90000");
print_envelope(@address_parts);

bad_print(@list, @address_parts);

sub run_together
{
    my (@list) = @_;
    my ($str, $string);

    $string = "";
    foreach $str (@list)
    {
         $string .= $str;
    }
    return $string;
}
    

sub print_envelope
{
    my ($name, $street, $city_state_zip) = @_;

    print "$name\n";
    print "$street\n";
    print "$city_state_zip\n\n";
}



sub bad_print
{
    my (@list1,@list2) = @_;
    my  $element;

    foreach $element (@list1)
    {
        print $element,"\n";   #####  Look at the output!!!!!!
    }
}
#########################  Program Execution Below  #####################

$ files-subs.pl files-subs.pl x

#!/usr/bin/perl -w
######################  Elementary File I/O  ############################
@lines = <INFILE>;  ####  Reads the whole file in ONE read!
                    ####  Each element of @lines is one \n-terminated line.
#####  Above is the same as:
#####  $line = 0; while (<INFILE>){@lines[$line++] = $_;}
     print OUTFILE $line if $line =~ m/#/;
#########  No, I don't need to close OUTFILE first before reopen!!
print while (<OUTFILE>);  #####  Idiomatic usage of $_ default!!
#############  Function Parameters of Scalar and List Type  ################
        print $element,"\n";   #####  Look at the output!!!!!!

foobarsnafuouchoops
John Doe
123 Main Street
Nowhere, CA 90000

foo
bar
snafu
ouch
oops
John Doe
123 Main Street
Nowhere, CA 90000

#######################  Important New Style Rules!  #######################

1.  Always check for the correct number of program arguments and die with
    a usage error if the number is not correct.

2.  If any argument has an improper value, die with an error message.

3.  Remember that if a program inspects multiple files in a loop and an
    error occurs with ONE file, you probably want to give an error message
    and move on to the next file.  Don't die!!

4.  Put argument checking at the top of the program. 

5.  Every sub's variables should be my'ed or, in some cases, local'ed.
    Remember that my variables are known only inside the sub and local
    variables are known in the current sub and any sub called by it.

6.  If <HANDLE> is not assigned to anything, it is automatically assigned
    to $_.  Print and many other Perl functions use $_ as a default argument.