Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

0 views
Skip to first unread message

Tomasz Chmielewski

unread,
Mar 28, 2008, 5:34:13 AM3/28/08
to
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?

--
Tomasz Chmielewski
http://wpkg.org

Gunnar Hjalmarsson

unread,
Mar 28, 2008, 6:16:25 AM3/28/08
to

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

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

John W. Krahn

unread,
Mar 28, 2008, 8:04:42 AM3/28/08
to
Tomasz Chmielewski 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
>
>
> 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
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall

Jim Cochrane

unread,
Mar 28, 2008, 2:57:05 PM3/28/08
to
On 2008-03-28, Tomasz Chmielewski <t...@nospam.syneticon.net> 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
>
>
>
> 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";

Willem

unread,
Mar 28, 2008, 3:18:19 PM3/28/08
to
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

Thrill5

unread,
Mar 29, 2008, 3:29:08 AM3/29/08
to

"Tomasz Chmielewski" <t...@nospam.syneticon.net> wrote in message
news:fsie2l$g0f$1...@online.de...

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.


Gunnar Hjalmarsson

unread,
Mar 29, 2008, 8:35:40 AM3/29/08
to
Thrill5 wrote:
> "Tomasz Chmielewski" <t...@nospam.syneticon.net> wrote in message
> news:fsie2l$g0f$1...@online.de...
>> 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?
>
> 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.

Tomasz Chmielewski

unread,
Mar 29, 2008, 11:41:45 AM3/29/08
to
Gunnar Hjalmarsson schrieb:

Thanks all in this thread for useful suggestions!

Joe Smith

unread,
Mar 31, 2008, 4:14:21 AM3/31/08
to
Tomasz Chmielewski wrote:
> 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 '') { ... }

-Joe

Peter Scott

unread,
Mar 31, 2008, 8:17:42 AM3/31/08
to

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

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

--
Peter Scott
http://www.perlmedic.com/
http://www.perldebugged.com/

szr

unread,
Mar 31, 2008, 1:08:59 PM3/31/08
to
Peter Scott wrote:
> On Mon, 31 Mar 2008 01:14:21 -0700, Joe Smith wrote:
>> Tomasz Chmielewski wrote:
>>> 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]) { ... }

--
szr


Gunnar Hjalmarsson

unread,
Mar 31, 2008, 1:27:07 PM3/31/08
to
szr wrote:
> Peter Scott wrote:
>> 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>

szr

unread,
Mar 31, 2008, 2:18:40 PM3/31/08
to

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
?

--
szr


Willem

unread,
Mar 31, 2008, 2:23:00 PM3/31/08
to
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.

Frank Seitz

unread,
Mar 31, 2008, 2:29:48 PM3/31/08
to
szr wrote:

> Gunnar Hjalmarsson wrote:
>>
>>use warnings;
>>@execargs = undef;

Better:
@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.
>

> 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.

> 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.

Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

szr

unread,
Mar 31, 2008, 7:24:41 PM3/31/08
to
Frank Seitz wrote:
> szr wrote:
>> Gunnar Hjalmarsson wrote:
>>>
>>> use warnings;
>>> @execargs = undef;
>
> 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.

--
szr


0 new messages