Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

use strict and warnings problems 5

Status
Not open for further replies.

nfaber

Technical User
Oct 22, 2001
446
US
What can I do to get rid of the "use of uninitialized value" warnings I get when I read a file into an array or hash when I know that some elements will not have any values. Is there some trick? What I have been doing is turning of warnings.

Thanks,

Nick
 
You can set up default values, then read in the file and override them. If you can give an example of how you're reading the values into the array or hash, then we can give you some ideas.

Barbie
Leader of Birmingham Perl Mongers
 
Thanks for the reply. Here is a snippet of a program I am writing:

Code:
foreach $dev (@device) {
		my ($log_name, $type, $uis_fstatus, $uis_managed_date, $uis_deactivated_date ) = split (/,/, $dev);
		my ($month, $day, $year, $time) = split (/-/,$uis_managed_date);
		my ($de_month, $de_day, $de_year, $de_time) = split (/-/,$uis_deactivated_date);
		next unless ($year);
		next unless {($month <= $rpt_month) || ($year < $rpt_yr)};
		next unless ($uis_fstatus =~ /managed/i);
		next unless ($log_name =~ /\.na\.$key/i);
		next if ($uis_fstatus =~ /un/i && $de_month != $rpt_month);
		next if ($type =~ /circuit/i);
		next if ($log_name =~ /imac/i);
		next if ($log_name =~ /default/i);
		if ($type		=~		/router/i)	{
			$rout_cnt++;
		}
		elsif ($type		=~		/switch/i)	{
			$swtch_cnt++;
		}
		elsif ($type		=~		/server/i)	{
			$sys_cnt++;
		}
		elsif ($type		=~		/ups/i)		{
			$ups_cnt++;
		}
		else {
			$oth_cnt++;
		}
	}
	my $total = ($rout_cnt + $swtch_cnt + $sys_cnt + $ups_cnt + $oth_cnt);

@device is the result of a query to a DB. In many instances the row that I query has many missing fields, hence my variables are assigned no values. That is ok however because I am only interested in the rows that do have all the values. The program works just fine, exactly what I want but I still get the warnings.

thanks,

Nick
 
could it be as simple as:

Code:
foreach $dev (@device) {
   next unless $dev;
   ...
 
KevinADC , correct me if i'm wrong,
I think he said some fields and this is for the whole line.


nfaber
If the problem is on the uninitialized values of the first line of the loop, then you could just place before the loop this line
Code:
my ($log_name, $type, $uis_fstatus, $uis_managed_date, $uis_deactivated_date ) = "";
make the loop like this
Code:
foreach $dev (@device) {
        ($log_name, $type, $uis_fstatus, $uis_managed_date, $uis_deactivated_date ) = split (/,/, $dev);
The same goes for the next two lines. Asing "" values, to the variables that you create, before the loop and inside the loop just dont use 'my'.
I hope that this will help.
 
That won't work, if you assign a value, then override it with undef, it'll still be undef. You'll want something like:

Code:
foreach $dev (@device) {
  my @fields = split (/,/, $dev);
  my $log_name             = $fields[0] || next;
  my $type                 = $fields[1] || next;
  my $uis_fstatus          = $fields[2] || next;
  my $uis_managed_date     = $fields[3] || next;
  my $uis_deactivated_date = $fields[4] || next;

  # other code
}

You'll need to use the '||' form of or due to precedence rules. If the field value is undefined, this will then force the logic to read the next device entry.

Barbie
Leader of Birmingham Perl Mongers
 
Thanks again for all the replies. It seems as though my choice is to add more programming or not use warnings. I am all for adhering to proper perl coding rules, and not getting sloppy, but what is th advantage of using warnings here?
 
using warnings is perl's way of saying that your code might suffer from insufficient programming. In a more strictly enforced language, your program wouldn't compile, and if it won't compile it won't be linkable, and if it can't be linked it'll never run.

[aside]you can pretty much force a compiler to ignore warnings, and generate a bodgy executable, but the executable will still be that[/aside]

The choice as they say is entirely yours, just remember if you change code, use warnings will advise you of potential problems.

Say for example you're using these unitialized values as keys for a hash, and you default them to some key 'undef' the possibility of key clashes, and thereby data loss due to overwriting are pretty high. If you're sure of your data, omit warnings, other than that, if the environment can advise of potential pitfalls, take note and eradicate the problem through code

My €0.02 at any rate

--Paul

cigless ...
 
Barb, I think
Code:
  my $log_name             = $fields[0] || next;
  my $type                 = $fields[1] || next;
  my $uis_fstatus          = $fields[2] || next;
  my $uis_managed_date     = $fields[3] || next;
  my $uis_deactivated_date = $fields[4] || next;
will do a next if any of the fields are zero, not just undefined.

If $dev is a comma-delimited string, why not just test to see if it contains 2 or more adjacent commas. This means one or more fields will be undefined after the split. E.g.
Code:
foreach my $dev (@device) {
  next if $dev =~ /,,+/;
  # or ... next if index($dev, ",,") > -1;
  my @fields = split (/,/, $dev);
...
This is much easier than testing each field after the split.

I heartily second what Paul says about warnings. Anything that keeps you from writing sloppy code is a Good Thing.



 
mike, you are quite right. That's what comes of thinking aloud and not testing. Bad Barbie, no biscuit! However, you're solution of check for adjacent commas is probably the simplest of the lot :)

Regarding warnings and strictures. If you talk to most experienced Perl programmers, particularly those who are well respected within the perl community, it is always seen as a must as having:

Code:
#!/usr/bin/perl -w
use strict;

at the top of your scripts. There are even some employers that will look badly on you if you don't do it.

Warnings and strictures are there to protect you. Perl is very loud about acknowledging that there are insecurities in programming. Perl makes a loud noises about them, because it wants you to program safely, not because its an inheritantly insecure language. In fact virtually every programming language can be deemed insecure, unless you practice good secure programming concepts. However, there times when you do want to turn off warnings and strictures (eg CGI scripts that are in production ... you can give too much away if something breaks badly), you must have a very good reason for doing so. There was a recent use.perl journal by Ovid, that puts this in to perspective.

At the end of the day, how hard is it to practice good programming skills? If it means you get into good habits of securing your code, is that really a bad thing? Before too long you'll be writing 'my', perhaps even using 'taint' without a second thought. Its worth the effort in the long run.

Barbie
Leader of Birmingham Perl Mongers
 
perluserpengo said:
KevinADC , correct me if i'm wrong,
I think he said some fields and this is for the whole line.

I knew it was a long shot, so there is nothing to correct. [wink]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top