empty variables - getting rid of "uninitialized value" warnings?

T

Tomasz Chmielewski

I have perl code which should do some action only if:

- the variable does not begin with "#" (commented out),
- the variable is not empty



use strict;
use warnings;

my @array = ("# Comment", "/usr/bin/binary --test", "");

foreach my $var (@array) {

my @execargs = split(/#/, $var);

if ( $execargs[0] ne '' ) { print "$var 0: |$execargs[0]|\n" }

}


Unfortunately, it shows uninitialized value warnings for the empty
variable (""):

$ perl test.pl
/usr/bin/binary --test 0: |/usr/bin/binary --test|
Use of uninitialized value $execargs[0] in string ne at test.pl line 14.



Using:

if ( defined $execargs[0] ) { print "$var 0: |$execargs[0]|\n" }

is not a solution either, because $execargs[0] will be defined for a
case with "# Comment" and an undesired action will be made for this element:


$ perl test.pl
# Comment 0: ||
/usr/bin/binary --test 0: |/usr/bin/binary --test|



How can I get rid of warnings if I make tests with "if" and some
variables are empty?

Should I just ignore it? Or use "no warnings" just for that piece of
code throwing a warning?
 
G

Gunnar Hjalmarsson

Tomasz said:
I have perl code which should do some action only if:

- the variable does not begin with "#" (commented out),
- the variable is not empty

use strict;
use warnings;

my @array = ("# Comment", "/usr/bin/binary --test", "");

foreach my $var (@array) {

my @execargs = split(/#/, $var);

if ( $execargs[0] ne '' ) { print "$var 0: |$execargs[0]|\n" }

}

Unfortunately, it shows uninitialized value warnings for the empty
variable (""):

$ perl test.pl
/usr/bin/binary --test 0: |/usr/bin/binary --test|
Use of uninitialized value $execargs[0] in string ne at test.pl line 14.

Using:

if ( defined $execargs[0] ) { print "$var 0: |$execargs[0]|\n" }

is not a solution either, because $execargs[0] will be defined for a
case with "# Comment" and an undesired action will be made for this
element:

$ perl test.pl
# Comment 0: ||
/usr/bin/binary --test 0: |/usr/bin/binary --test|

How can I get rid of warnings if I make tests with "if" and some
variables are empty?

Should I just ignore it? Or use "no warnings" just for that piece of
code throwing a warning?

foreach my $var (@array) {
next unless defined $var and length $var;
next if substr($var, 0, 1) eq '#';
print "$var\n";
}
 
J

John W. Krahn

Tomasz said:
I have perl code which should do some action only if:

- the variable does not begin with "#" (commented out),
- the variable is not empty


use strict;
use warnings;

my @array = ("# Comment", "/usr/bin/binary --test", "");

foreach my $var (@array) {

my @execargs = split(/#/, $var);

if ( $execargs[0] ne '' ) { print "$var 0: |$execargs[0]|\n" }

}


Unfortunately, it shows uninitialized value warnings for the empty
variable (""):

$ perl test.pl
/usr/bin/binary --test 0: |/usr/bin/binary --test|
Use of uninitialized value $execargs[0] in string ne at test.pl line 14.

$ perl -le'
use strict;
use warnings;
my @array = ( "# Comment", "/usr/bin/binary --test", "" );
foreach my $var ( @array ) {
next if $var =~ /^(?:#|$)/;
print $var;
}
'
/usr/bin/binary --test




John
 
J

Jim Cochrane

I have perl code which should do some action only if:

- the variable does not begin with "#" (commented out),
- the variable is not empty



use strict;
use warnings;

my @array = ("# Comment", "/usr/bin/binary --test", "");

foreach my $var (@array) {

my @execargs = split(/#/, $var);

if ( $execargs[0] ne '' ) { print "$var 0: |$execargs[0]|\n" }

}

If I understand what you're trying to do (and perhaps I don't), you want
something like this:

#!/usr/bin/perl

use strict;
use warnings;

my @array = ("# Comment",
"/usr/bin/binary --test1",
"/usr/bin/binary --test2",
"/usr/bin/binary\t--test3",
" /usr/bin/binary --test4",
"");

for my $var (@array) {
if (not $var or $var =~ /^#/) {
next;
}
my @execargs = split(' ', $var);
print 'arg array: ' . join(', ', @execargs) . "\n";
}

Unfortunately, it shows uninitialized value warnings for the empty
variable (""):

$ perl test.pl
/usr/bin/binary --test 0: |/usr/bin/binary --test|
Use of uninitialized value $execargs[0] in string ne at test.pl line 14.



Using:

if ( defined $execargs[0] ) { print "$var 0: |$execargs[0]|\n" }

is not a solution either, because $execargs[0] will be defined for a
case with "# Comment" and an undesired action will be made for this element:


$ perl test.pl
# Comment 0: ||
/usr/bin/binary --test 0: |/usr/bin/binary --test|



How can I get rid of warnings if I make tests with "if" and some
variables are empty?

Should I just ignore it? Or use "no warnings" just for that piece of
code throwing a warning?


--
 
W

Willem

Tomasz wrote:
) I have perl code which should do some action only if:
)
) - the variable does not begin with "#" (commented out),
) - the variable is not empty

That's not quite what your code indicates is your intention.

It looks more like:
- Print only the part of a line before the '#'
- Don't print of the above is empty.


) my @array = ("# Comment", "/usr/bin/binary --test", "");
)
) foreach my $var (@array) {
)
) my @execargs = split(/#/, $var);
)
) if ( $execargs[0] ne '' ) { print "$var 0: |$execargs[0]|\n" }
)
) }
)
)
) Unfortunately, it shows uninitialized value warnings for the empty
) variable (""):
)
) $ perl test.pl
) /usr/bin/binary --test 0: |/usr/bin/binary --test|
) Use of uninitialized value $execargs[0] in string ne at test.pl line 14.
)
)
)
) Using:
)
) if ( defined $execargs[0] ) { print "$var 0: |$execargs[0]|\n" }
)
) is not a solution either, because $execargs[0] will be defined for a
) case with "# Comment" and an undesired action will be made for this element:

How about just:

if ($execargs[0]) ?

And how about:
my ($execarg) = split(/#/, $var);
and then:
if ($execarg) { ... }


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
G

Gunnar Hjalmarsson

Thrill5 said:
Try:
use strict;
use warnings;
no warnings 'uninitialized';

This will turn off only the uninitialized variable warnings, and keep all
the other warnings. I find those warnings are more trouble to get rid of
then the value that the warning provides.

Even if that may be true in some cases, it's not true in this case IMO.
If you write code that does not generate such warnings, you increase the
chance that there are no bugs. The OP has already received a few
suggestions.

Also, if you want to disable 'uninitialized' warnings, you'd better do
so in the block(s) where it's needed, and not disable them for the whole
program.
 
T

Tomasz Chmielewski

Gunnar said:
Even if that may be true in some cases, it's not true in this case IMO.
If you write code that does not generate such warnings, you increase the
chance that there are no bugs. The OP has already received a few
suggestions.

Also, if you want to disable 'uninitialized' warnings, you'd better do
so in the block(s) where it's needed, and not disable them for the whole
program.

Thanks all in this thread for useful suggestions!
 
P

Peter Scott

Tomasz said:
use strict;
use warnings;
...
if ( $execargs[0] ne '' ) { ..... }

Whenever you are using warnings, you should never attempt to use
an array element without first testing that it is there.

if (@execargs and $execargs[0] ne '') { ... }

Not quite good enough. The element could exist but be undef.

if (defined $execargs[0] && $execargs[0] ne '') { ... }
 
S

szr

Peter said:
Tomasz said:
use strict;
use warnings;
...
if ( $execargs[0] ne '' ) { ..... }

Whenever you are using warnings, you should never attempt to use
an array element without first testing that it is there.

if (@execargs and $execargs[0] ne '') { ... }

Not quite good enough. The element could exist but be undef.

if (defined $execargs[0] && $execargs[0] ne '') { ... }

Instead of checking for definity, you could check for existance too:

if (exists $execargs[0] && $execargs[0] ne '') { ... }

Or even:

if (exists $execargs[0] && !!$execargs[0]) { ... }
 
G

Gunnar Hjalmarsson

szr said:
Peter said:
if (@execargs and $execargs[0] ne '') { ... }

Not quite good enough. The element could exist but be undef.

if (defined $execargs[0] && $execargs[0] ne '') { ... }

Instead of checking for definity, you could check for existance too:

if (exists $execargs[0] && $execargs[0] ne '') { ... }

I think you missed the point...

C:\home>type test.pl
use warnings;
@execargs = undef;
if (exists $execargs[0] && $execargs[0] ne '') {
# ...
}

C:\home>perl test.pl
Use of uninitialized value $execargs[0] in string ne at test.pl line 3.

C:\home>
 
S

szr

Gunnar said:
szr said:
Peter said:
On Mon, 31 Mar 2008 01:14:21 -0700, Joe Smith wrote:

if (@execargs and $execargs[0] ne '') { ... }

Not quite good enough. The element could exist but be undef.

if (defined $execargs[0] && $execargs[0] ne '') { ... }

Instead of checking for definity, you could check for existance too:

if (exists $execargs[0] && $execargs[0] ne '') { ... }

I think you missed the point...

C:\home>type test.pl
use warnings;
@execargs = undef;
if (exists $execargs[0] && $execargs[0] ne '') {
# ...
}

C:\home>perl test.pl
Use of uninitialized value $execargs[0] in string ne at test.pl line
3.
C:\home>

I ran the same test and got the same result.

Removing the " && $execargs[0] ne '' " portion prevented the error.

This works too:

if (exists $execargs[0] && !!$execargs[0]) {

(Tested in 5.10.0, 5.8.8, and 5.6.1)


So I wonder, since " exists $execargs[0] " fails, why does it still
evaluate " && $execargs[0] ne '' " , thus causing the error.

This happens in all 3 versions I tested with. Is this a bug? I thought
it is supposed to short-circuit if the first expr fails in an && or AND
?
 
W

Willem

szr wrote:
) I ran the same test and got the same result.
)
) Removing the " && $execargs[0] ne '' " portion prevented the error.
)
) This works too:
)
) if (exists $execargs[0] && !!$execargs[0]) {
)
) (Tested in 5.10.0, 5.8.8, and 5.6.1)
)
)
) So I wonder, since " exists $execargs[0] " fails, why does it still
) evaluate " && $execargs[0] ne '' " , thus causing the error.
)
) This happens in all 3 versions I tested with. Is this a bug? I thought
) it is supposed to short-circuit if the first expr fails in an && or AND
) ?

It may be an operator precedence issue.
Try 'and' instead of '&&', or use parentheses around the second expression.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
S

szr

Frank said:
Better:
@execargs = (undef);

Yes. The effect is the same, but this makes it clearer. Why someone
would do this in practice is another question entirely, though.
if (exists $execargs[0] && $execargs[0] ne '') {
# ...
}

C:\home>perl test.pl
Use of uninitialized value $execargs[0] in string ne at test.pl line
3.

I ran the same test and got the same result.

Removing the " && $execargs[0] ne '' " portion prevented the error.

Yes, because this test produces the warning.

Yes I now understand why it was coming out that way, thanks.
This works too:

if (exists $execargs[0] && !!$execargs[0]) {

(Tested in 5.10.0, 5.8.8, and 5.6.1)

So I wonder, since " exists $execargs[0] " fails,

No, "exists $execargs[0]" succeeds, because there is an element 0.

Oh, yeah, because of the assingment of C<undef> to the array. My brain,
for whatever reason, translated that into C<@execargs = ()> as if it was
the same.

Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top