f



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

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
0
Tomasz
3/28/2008 9:34:13 AM
comp.lang.perl.misc 33233 articles. 2 followers. brian (1246) is leader. Post Follow

15 Replies
303 Views

Similar Articles

[PageSpeed] 42

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.
> 
> 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";
     }

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
0
Gunnar
3/28/2008 10:16:25 AM
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
0
John
3/28/2008 12:04:42 PM
On 2008-03-28, Tomasz Chmielewski <tch@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";
}


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


-- 

0
Jim
3/28/2008 6:57:05 PM
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
0
Willem
3/28/2008 7:18:19 PM
"Tomasz Chmielewski" <tch@nospam.syneticon.net> wrote in message 
news:fsie2l$g0f$1@online.de...
>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

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. 


0
Thrill5
3/29/2008 7:29:08 AM
Thrill5 wrote:
> "Tomasz Chmielewski" <tch@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.

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
0
Gunnar
3/29/2008 12:35:40 PM
Gunnar Hjalmarsson schrieb:
> Thrill5 wrote:
>> "Tomasz Chmielewski" <tch@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.

Thanks all in this thread for useful suggestions!


-- 
Tomasz Chmielewski
http://wpkg.org


0
Tomasz
3/29/2008 3:41:45 PM
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
0
Joe
3/31/2008 8:14:21 AM
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 '') { ... }

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

0
Peter
3/31/2008 12:17:42 PM
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 


0
szr
3/31/2008 5:08:59 PM
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>

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
0
Gunnar
3/31/2008 5:27:07 PM
Gunnar Hjalmarsson wrote:
> 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>

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 


0
szr
3/31/2008 6:18:40 PM
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
0
Willem
3/31/2008 6:23:00 PM
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
0
Frank
3/31/2008 6:29:48 PM
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
szr
3/31/2008 11:24:41 PM
Reply: