Hi Charles,
        I am really thankful for your detailed explanation. I will try to
gain as much as I can from this mail.

With Regards,
Sridhar Reddy T.

-----Original Message-----
From: Charles K. Clarkson [mailto:[EMAIL PROTECTED] 
Sent: Monday, October 17, 2005 12:15 AM
To: 'Perl Beginners'
Subject: RE: I need help here

Sreedhar reddy <mailto:[EMAIL PROTECTED]> wrote:
: Hi Charles,
:
:
: This is the code which I have written to finish my small task...

    Oh. So I actually had the whole thing to begin with. Sorry
about that.


    Your script is using a different set of variables than the
ones we would like to see you use. Mark J Dominus wrote an article
for The Perl Journal in 1998. The full article is "reprinted" at
http://perl.plover.com/FAQs/Namespaces.html

<quote "unix dumb quotes edited">

 Here's the Big Secret about Perl variables that most people learn
 too late: Perl has two completely separate, independent sets of
 variables. One is left over from Perl 4, and the other is new.
 The two sets of variables are called 'package variables' and
 'lexical variables', and they have nothing to do with each other.

</quote>

    While this was a secret in 1998 and while it is true that some
perl programmers still choose package variables over lexical
variables, we, the perl community, would like to follow Mark's
warning and introduce beginners to lexical variables from the
start.

    Your script should start with these modules. They help you
by discouraging some actions. They also catch many typos. And
they limit you from accidentally using package variables.

use strict;
use warnings;

    You might also add this module. It will give you a better idea
about how to solve errors (and even where to go for research).

use diagnostics;

    So, for a while your scripts should start like this.

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;



: $inputfile= shift;
: $outputfile = shift;

    To change these package variables to lexical variables, we
need only use the 'my' function. I also like to line up equality
signs when writing code and to separate words in a variable name
with an underscores and, like you, everything is in lowercase.

my $input_file  = shift;
my $output_file = shift;


    You will often see a usage message in a script which deals
with the command line. It's good to use it for your own utilities
as well. Eight months from now you may have forgotten what belongs
on the command line or what this utility does. usage() is a
subroutine in the script which tells users what the script does
and what is expected on the commend line.

usage() if @ARGV < 2;

my $input_file  = shift;
my $output_file = shift;

# or:

usage() if @ARGV < 2;

my( $input_file, $output_file ) = @ARGV;

    When perl evaluates the Boolean "@ARGV < 2" it uses the scalar
value of @ARGV which is the count of its elements. We want at
least 2 items in there.

sub usage {
    print qq(Usage:\n\n$0 INPUT_FILE OUTPUT_FILE\n\n);
    print qq(This utility will . . . );
    exit;
}

    You might take the time to make your usage statements match
the style used by your operating system. Then users can quickly
grasp what your script does and how to use it. ($0 is a built in
perl variable. You can read more about these variables in the
'perlvar' file of the perl documentation.)



:   open(FILE1,"<$inputfile");
:   @lines=<FILE1>;
:   close(FILE1);
:   open(FILE2,">$outputfile");

    Even with strict variables enforced, we still tend to use
package variables in some traditional ways. FILE1 and FILE2 are
file handles. Or perhaps they are references to file handles. I'm
not really sure. But they are package variables.

    Almost all programs you run across use this style and strict
allows it, but I don't like it. Perl 5.6.0 allowed us to stop
using these in favor of lexical variables.

open( my $fh, "<$input_file" );
    
<quote "perldoc -f open">

 If FILEHANDLE is an undefined scalar variable (or array or hash
 element) the variable is assigned a reference to a new anonymous
 filehandle, otherwise if FILEHANDLE is an expression, its value
 is used as the name of the real filehandle wanted. (This is
 considered a symbolic reference, so "use strict 'refs'" should
 *not* be in effect.)

</quote>

    While this is a better way, it hasn't caught on yet. So please
don't feel confused when you see some of us use FH and FILE
and others use $fh and $fh_in (lexical variables).

    Not being a big fan of excess parenthesis, I would rewrite
your statement as below. I am using the three argument form for
open. You can read more about it in "perlopentut" in the perl
docs. It will also explain why I am checking for success on the
file open and the file close. (Many people don't check the closing
for an error.)

    I tend to be lean on variable use. Reusing variables when
it doesn't hurt readability. YMMV. So I just reused $fh as my file
handle for the output file.


open my $fh, '<', $input_file or die qq(Cannot open "$input_file": $!);

my @lines = <$fh>;

close $fh or die qq(Cannot close "$input_file": $!);

open $fh, '>', $output_file or die qq(Cannot open "$output_file": $!);



: foreach $line (@lines) {

    $line is a package variable. Let's make it lexical.

foreach my $line (@lines) {


:   if($line =~ m/(\d+) ([a-z,A-Z,_,0-9]+)/)             /*  to write
: this line I have taken lot of time as I know basics in Regular
: Expressions */

    You can use POD commands for multi-line comments, but the perl
comment operator is "#". /* and */ don't work as perl comments.

    # to write this line I have taken lot of time as I know
    # basics in Regular Expressions
    if ( $line =~ m/(\d+) ([a-z,A-Z,_,0-9]+)/ )

    And a fine job you did with it too. Though you probably don't
want the commas in the character class. They are not doing what
you think ( [a-zA-Z_0-9] ). The difference is that your character
class allowed the comma "," as a valid character.


:   {
:           print FILE2 "$2 $1\n";
:   }
: }
: close(FILE2);
: print "\n"

HTH,

Charles K. Clarkson
-- 
Mobile Homes Specialist
254 968-8328


#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

usage() if @ARGV < 2;

my $input_file  = shift;
my $output_file = shift;

# Input
open my $fh, '<', $input_file or die qq(Cannot open "$input_file": $!);
my @lines = <$fh>;
close $fh or die qq(Cannot close "$input_file": $!);

# Output
open $fh, '>', $output_file or die qq(Cannot open "$output_file": $!);
foreach my $line (@lines) {

    # To write this line I have taken lot of time as I know
    # basics in Regular Expressions.
    print $fh "$2 $1\n" if $line =~ m/(\d+) ([a-z,A-Z,_,0-9]+)/;
}
close $fh or die qq(Cannot close "$output_file": $!);

sub usage {
    # Lame usage message.
    print qq(Usage:\n\n$0 INPUT_FILE OUTPUT_FILE\n\n);
    print qq(This utility will . . . );
    exit;
}

__END__


    OR:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

usage() if @ARGV < 2;

my $input_file  = shift;
my $output_file = shift;

# Input and output
open my $fh_in,  '<', $input_file  or die qq(Cannot open "$input_file": $!);
open my $fh_out, '>', $output_file or die qq(Cannot open "$output_file":
$!);

while ( <$fh_in> ) {
    print $fh_out "$2 $1\n" if m/(\d+) ([a-z,A-Z,_,0-9]+)/;
}

close $fh_in  or die qq(Cannot close "$input_file": $!);
close $fh_out or die qq(Cannot close "$output_file": $!);

sub usage {
    # Lame usage message.
    print qq(Usage:\n\n$0 INPUT_FILE OUTPUT_FILE\n\n);
    print qq(This utility will . . . );
    exit;
}

__END__



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>





-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to