weird behaviour

0 views
Skip to first unread message

Jayaprakash Rudraraju

unread,
Mar 22, 2002, 12:07:28 PM3/22/02
to

Dear Experts,

The following simple program for parsing command line arguments is giving
me weird output. I have spent 3 hours trying to find out the reason for
it's weird behaviour. Can you please figure out the mistake in the
program.

#!/usr/local/bin/perl -w

my (%option_values, ) = ();

&ParseOptions("fsa", MU, "freq", MU, "flanking", MU, "snp", MLC,
"outfile", MU, );

my ($fsa, $freq, $flanking, @snp, $outfile, ) =
(@{$option_values{fsa}}[0], @{$option_values{freq}}[0],
@{$option_values{flanking}}[0], @{$option_values{snp
}}, @{$option_values{outfile}}[0], );

print "option: snp - value: @{$option_values{snp}}\n";
print "option: outfile - value: @{$option_values{outfile}}[0]\n";
print "option: snp - value: @snp\n";
print "option: outfile - value: $outfile\n";

sub ParseOptions {

# Variable Declarations
local ($usage, $arg, $option, %options, %describe, ) = ();

# Describe each Option
%describe = ( fsa => "fsa input filename",
freq => "freq input filename",
flanking => "num - 300, 100",
snp => "comma seperated snp values",
outfile => "output filename",
# help => "display this text",
);

while(@_) {
$arg = shift(@_);
$options{$arg} = shift(@_);
}

# Creates USAGE string
$usage = "\nUSAGE:\n";
foreach my $key (sort keys %options) {
$usage = "$usage\t<-$key>\t[$describe{$key}]\n";
}

# 1) Checks zero argument list
# 2) Checks for valid option types.
# 3) Creates lists for each given option.

die "$usage\n" unless @ARGV;
while (defined($arg = shift(@ARGV))) {
if($arg =~ /^-/) {
$arg = substr($arg, 1);
die "$usage\n" unless exists $options{$arg};
$option = $arg;
} else {
die "$usage\n" unless defined $option;
push(@{$option_values{$option}}, split(/,/, $arg))
if $arg =~ /,/;
push(@{$option_values{$option}}, $arg) unless $arg
=~ /,/;
}
}
}


Now the output:

[unknown] /data4/tlr2_abi>./ABIorder.pl -flanking 300 -freq
TLR02_PGA_SNPs5.freq.txt -fsa TLR2.fsa -snp 677,61381 -outfile
abi_output.txt
Name "main::defaults" used only once: possible typo at ./ABIorder.pl line
17.
option: snp - value: 677 61381
option: outfile - value: abi_output.txt
option: snp - value: 677 61381 abi_output.txt
Use of uninitialized value at ./ABIorder.pl line 12.
option: outfile - value:


Please ignore first error.

Thanks,
Prakash.

Brian McCauley

unread,
Mar 22, 2002, 12:45:30 PM3/22/02
to
Jayaprakash Rudraraju <pra...@ece.arizona.edu> writes:

> Subject: weird behaviour

Please be less selfish in your subject lines.

> The following simple program for parsing command line arguments

There are Getopts modules you know.

> is giving
> me weird output. I have spent 3 hours trying to find out the reason for
> it's weird behaviour. Can you please figure out the mistake in the
> program.

Take you program and simplify it until it stops behaving weird. The
last bit you removed is probably the bit that is causing the weird
behaviour.

It would help if you explained what it was about your program's
behaviour that you consider wierd.

> #!/usr/local/bin/perl -w

You forgot use strict.

> my (%option_values, ) = ();
>
> &ParseOptions("fsa", MU, "freq", MU, "flanking", MU, "snp", MLC,
> "outfile", MU, );

Why is that & there? If the answer is "I don't know" then remove it
and someday when you've nothign better to do look up what it means.

Also avoid use of barewords. Use strict would have helped you with
this.

> my ($fsa, $freq, $flanking, @snp, $outfile, ) =
> (@{$option_values{fsa}}[0], @{$option_values{freq}}[0],
> @{$option_values{flanking}}[0], @{$option_values{snp
> }}, @{$option_values{outfile}}[0], );

This can never assign $outfile, the first array or hash on the LHS of
a list assignment will eat up all the remainder of the RHS.

> # Variable Declarations
> local ($usage, $arg, $option, %options, %describe, ) = ();

local() does not declare variables. Putting a comment in front saying
"Variable Declarations" won't alter this fact.

> push(@{$option_values{$option}}, split(/,/, $arg))
> if $arg =~ /,/;
> push(@{$option_values{$option}}, $arg) unless $arg
> =~ /,/;

Do you really think that that is more efficient than simply spliting
always?

push(@{$option_values{$option}}, split(/,/, $arg));


--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\

Jayaprakash Rudraraju

unread,
Mar 22, 2002, 1:21:49 PM3/22/02
to

Thanks for pointing out the mistake and importantly for your valuble
comments on my code.

On 22 Mar 2002, Brian McCauley wrote:

> Jayaprakash Rudraraju <pra...@ece.arizona.edu> writes:
>
> > Subject: weird behaviour
>
> Please be less selfish in your subject lines.

My frustration made me write like that. You made me a happy man now.

>
> > The following simple program for parsing command line arguments
>
> There are Getopts modules you know.
>

I will start using modules only after I feel that I am comfortable with
perl.

> > is giving
> > me weird output. I have spent 3 hours trying to find out the reason for
> > it's weird behaviour. Can you please figure out the mistake in the
> > program.
>
> Take you program and simplify it until it stops behaving weird. The
> last bit you removed is probably the bit that is causing the weird
> behaviour.
>
> It would help if you explained what it was about your program's
> behaviour that you consider wierd.
>
> > #!/usr/local/bin/perl -w
>
> You forgot use strict.
>
> > my (%option_values, ) = ();
> >
> > &ParseOptions("fsa", MU, "freq", MU, "flanking", MU, "snp", MLC,
> > "outfile", MU, );
>
> Why is that & there? If the answer is "I don't know" then remove it
> and someday when you've nothign better to do look up what it means.
>

Since you are interested, let me explain you. :-)

I wanted to write a very general Parse_Options subroutine that would
validate and take different command line options. Here is how I have
divided all the possible kinds of command line options I could think of:

------

M - Mandatory: this option must be specified otherwise die "$usage\n";
O - Optional:
N[0..9] - Optional except one Mandatory.
Ex: if 2 options are N1, N1 - only one of them is Mandatory

--------

U - Unique: single value option
L - List: Multiple Value option

--------

C - Comma seperated list values
S - Space seperated.

-------


> Also avoid use of barewords. Use strict would have helped you with
> this.
>

I will do it. Thanks.

> > my ($fsa, $freq, $flanking, @snp, $outfile, ) =
> > (@{$option_values{fsa}}[0], @{$option_values{freq}}[0],
> > @{$option_values{flanking}}[0], @{$option_values{snp
> > }}, @{$option_values{outfile}}[0], );
>
> This can never assign $outfile, the first array or hash on the LHS of
> a list assignment will eat up all the remainder of the RHS.
>

:-) :-)

> > # Variable Declarations
> > local ($usage, $arg, $option, %options, %describe, ) = ();
>
> local() does not declare variables. Putting a comment in front saying
> "Variable Declarations" won't alter this fact.
>
> > push(@{$option_values{$option}}, split(/,/, $arg))
> > if $arg =~ /,/;
> > push(@{$option_values{$option}}, $arg) unless $arg
> > =~ /,/;
>
> Do you really think that that is more efficient than simply spliting
> always?
>
> push(@{$option_values{$option}}, split(/,/, $arg));
>
>

I initially had the same line, but while trying to debug I have added
those to check the what my program is doing when $arg had "," in it.

Thanks a lot.
Prakash.

> --
> \\ ( )
> . _\\__[oo
> .__/ \\ /\@
> . l___\\
> # ll l\\
> ###LL LL\\
>

Prakash

James Taylor

unread,
Mar 22, 2002, 1:39:12 PM3/22/02
to
In article <Pine.SOL.4.31.020322...@ece2.ece.arizona.edu>,

Jayaprakash Rudraraju <pra...@ece.arizona.edu> wrote:
>
> The following simple program for parsing command line arguments is giving
> me weird output. I have spent 3 hours trying to find out the reason for
> it's weird behaviour. Can you please figure out the mistake in the
> program.

I haven't checked the whole thing in detail but a few things
leap out at me. Firstly, you are consistently saying @{something}[0]
when you probably mean to say ${something}[0]. Secondly, there appear
to be several barewords here:

> &ParseOptions("fsa", MU, "freq", MU, "flanking", MU, "snp", MLC,
> "outfile", MU, );

Thirdly, you have a newline in an unquoted hash subscript:

> @{$option_values{flanking}}[0], @{$option_values{snp
> }}, @{$option_values{outfile}}[0], );

Fourthly, why are you using local() in the subroutine for
these variables:

> # Variable Declarations
> local ($usage, $arg, $option, %options, %describe, ) = ();

All in all, I'm very surprised that -w did not throw up more
warnings than you reported in your output, and I definitely
recommend that you make sure your program runs under the
"use strict" pragma if you want to remain sane.

--
James Taylor <james (at) oakseed demon co uk>
Based in Southam, Cheltenham, UK.
PGP key available ID: 3FBE1BF9
Fingerprint: F19D803624ED6FE8 370045159F66FD02

Eric J. Roode

unread,
Mar 22, 2002, 7:43:23 PM3/22/02
to
On Fri, 22 Mar 2002 10:07:28 -0700, Jayaprakash Rudraraju <pra...@ece.arizona.edu> wrote:

Want some constructive criticism?

> my ($fsa, $freq, $flanking, @snp, $outfile, ) =
> (@{$option_values{fsa}}[0], @{$option_values{freq}}[0],
> @{$option_values{flanking}}[0], @{$option_values{snp
> }}, @{$option_values{outfile}}[0], );

1) Do you really believe this is clearer or otherwise better than:

my $fsa = @{$option_values{fsa}}[0];
my $freq = @{$option_values{freq}}[0];
my $flanking = @{$option_values{flanking}}[0];
my @snp = @{$option_values{snp}};
my $outfile = @{$option_values{outfile}}[0];

2) It is rather better to write

my $fsa = $option_values{fsa}[0];

For now, take my word for it. When you know perl better, you'll
understand. If nothing else, you have to admit it's clearer.

----------------------------------------------------------------------
Eric J. Roode er...@myxa.com
Senior Software Engineer, Myxa Corporation
perl -lpe "(($0 =~ '/' ? ($_ = $0 ) =~ s!\.?/!?$!:$@;~~@@~~~NO CARRIER


Rafael Garcia-Suarez

unread,
Mar 23, 2002, 5:24:16 AM3/23/02
to
Jayaprakash Rudraraju wrote in comp.lang.perl.misc :

>
> I will start using modules only after I feel that I am comfortable with
> perl.

Probably what makes Perl superior to other equivalent languages is, in
my opinion, the CPAN.

You aren't fully comfortable with Perl until you know how to find and use
modules (esp. the most common ones).

--
Rafael Garcia-Suarez : http://rgarciasuarez.free.fr/

Reply all
Reply to author
Forward
0 new messages