QUOTE(Sun751 @ 18 Jun, 2009 - 11:22 PM)

I am reading a file and initializing the hash with respective segment. And i have used following loop,
I am wondering if there is any smart way of doing this task, i mean better than what I have done.
Let's take a look, hmm?
CODE
$line =~ s/\r\n//; #Subsitute binary character \cM\cJ
chomp($line);
These two lines are redundant. chomp removes the trailing (OS-dependent) newline from a value if there is a trailing newline. In theory, the chomp alone should be sufficient, but, in practice, it doesn't work so well if the file's line endings are different from those on the OS where the code is run, so I'd suggest using "$line =~ tr/\r\n//d" on its own, as this will remove any and all \r or \n characters from the line, whether they appear individually or paired (and tr/// runs faster than a full-blown regex).
CODE
if ($line eq "[RESOURCE]"){$RFlag = "WHITE"};
if ($line eq "[WNT]"){$WFlag = "WHITE";$RFlag = "RED"};
if ($line eq "[UNX]"){$UFlag = "WHITE";$WFlag = "RED"};
This looks to me like you're trying to implement a simple state machine using flags to indicate whether you're in a "RESOURCE", "WNT", or "UNX" section, but it's unclear why you're using two flags instead of just one. I suspect that
CODE
if ($line =~ /^\[([A-Z ]+)\]/) { $section_flag = $1 };
# or, with a more Perlish accent:
# $section_flag = $1 if $line =~ /^\[([A-Z ]+)\]/;
would be an easier and cleaner way to accomplish this, plus it will automatically catch any lines containing "[ALL CAPS TEXT]" if new section types are added later, although you may need to alter the regex to allow a broader range of characters than just uppercase letters and spaces.
This method is also less fragile in the case of files with out-of-order sections. The rest of your code seems to assume that only one of $RFlag, $WFlag, or $UFlag will be "WHITE" at any given time, but an input file with the [UNX] section first, then [WNT], then [RESOURCE] would set all three to "WHITE", violating this assumption.
The remaining code appears to be identical for all three sections, aside from which hash the "Source" values are inserted into, so they can be stripped down to:
CODE
if ($line =~ /^Id/)
{
$key = $line;
}
elsif ($line =~ /^Source/)
{
$$$results{$section_flag}{$key} = $line;
}
$results{RESOURCE}, $results{WNT}, and $results{UNX} will then correspond to your \%HR_resource, \%HR_Window, and \%HR_Linux, respectively.
Also note that I removed the double quotes around "$line" in the assignment to the hash and the trailing ".*?$" from the regexes, as they were superfluous.
Putting this all together, we get (syntactically valid, but completely untested):
CODE
while (my $line = <FILEREAD>)
{
$line =~ tr/\r\n//d; #Remove binary characters \cM and \cJ
if ($line)
{
if ($line =~ /^\[([A-Z ]+)\]/)
{
$section_flag = $1;
}
elsif ($line =~ /^Id/)
{
$key = $line;
}
elsif ($line =~ /^Source/)
{
$$$results{$section_flag}{$key} = $line;
}
}
}
which should behave identically to the code you posted, within the assumed constraints that input files must contain a [RESOURCE] section followed by a [WNT] section and then a [UNX] section and that you don't care what happens with data found in any section(s) other than those three.