note
rjt
<p>You're getting there. Nice to see you coming back with improving iterations. Comments by section, below:</p>
<h2>First of all...</h2>
<p>I can tell by looking that your code won't work--you're interchanging <c>%delList</c> and <c>%del</c>, for example. Make it easier on us, please: test your own programs.</p>
<p>That being said, there is still plenty I can tell you about your code.</p>
<h2>The <c>DELLIST</c> loop</h2>
<p>You deviated from my example in several important aspects:</p>
<p>I'm not sure why you've gone with the bareword filehandle approach. Best practice (as in my example) is to go with a lexical filehandle with <c>my</c>.</p>
<p>Second: Hash and array members are always scalars, so the sigil is always <c>$</c> in Perl 5 (unless you're working with slices, but that doesn't apply here.) So your <c>%delList{...}</c> should be <c>$delList{...}</c>, to access individual hash elements. Your @array usage appears to be correct.</p>
<p>Third: Re-read [doc://chomp] carefully. You're using its return as a hash key value, but it returns "the total number of characters removed from all its arguments", which is not what you want. You want the <c>chomp</c>'d string. That's why I did <c>chomp</c> first and then stuck <c>$_</c> into the hash.</p>
<p>Last, to answer your question about hashes and why all of the values are set to 1, first let me make sure you're not talking about <i>keys</i>. With your code as-is, probably every key will be set to 1, because that's what <c>chomp</c> will return for each line (each line has one newline). With me so far?</p>
<p>Hash <i>keys</i> are the strings used to address data elements in the hash. Hash <i>values</i> are the scalars containing whatever data you want to be associated with each key. For example:</p>
<code>my %age; # Age of a person, in years
$age{'Sonny'} = 30;
$age{'Junior'} = 10;
$age{'Poppa'} = 40;
foreach my $person (sort keys %age) {
print "$person is $age{$person} years old\n";
}
</code>
<p>In your case, we want to know <i>if</i> a certain entry should be written to one file or another. The way we define that is, if a key [doc://exists] in <c>%dellist</c> for that entry, that entry should be written to "beepon", else it's written to "beepoff". (What these names mean, I have no idea, by the way.) We assign 'something' a true value in <c>%dellist</c> with <c>$dellist{'something'} = 1</c>. In the loop, that 'something' happens to be the line that was read from the $dellist filehandle, minus the trailing newline.</p>
<p>Efficiency of scanning a list (your old method) versus using a hash is something similar to opening every drawer in your chest of drawers one by one until you find one that has socks, versus remembering that <c>$drawer{'socks'}</c> is <c>'topleft'</c> and just opening the top left drawer. Like most analogies, it's not perfect, but describes the efficiency gain fairly well.</p>
<h2>foreach</h2>
<p>Your for loop looks mostly functional, but you don't need to use C-style constructs, and you certainly don't need to read the entire file into an array first (waste of memory, possibly significant). You also don't need a clumsy if/else; there's a fabulous example of how to specify a filehandle as an expression right in [doc://print].</p>
<code>
open my $orglist, '<', $ARGV[1] or die "Can't open $ARGV[1]: $!";
foreach my $item (<$orglist>) {
chomp($item);
print { exists $dellist{$item} ? $beepon : $beepoff } $item . "\n";
}
close $orglist;
</code>
<p>Of course, the above assumes you've already done away with the bareword filehandles in favour of scalars.</p>
844319
844953