On Oct 10, 11:57 am, [EMAIL PROTECTED] (Kevin Zembower) wrote: > I've got a file that looks like this (using cat -vet to show tabs as > ^I): > > [EMAIL PROTECTED]: $ cat -vet /tmp/PeopleFinderDepartments.txt > 1^IH.07$ > 2^IH.22$ > 3^IH.30$ > 4^IH.32$ > 5^IH.32.01$ > 6^IH.32.05$ > 7^IH.32.06$ > [EMAIL PROTECTED]: $ > > I want to write a script that will use these values to replace the > numeric codes with the codes starting with "H..." If I read it using > straight variables, it seems to work fine: > > [EMAIL PROTECTED]: $ perl -e 'open T, "/tmp/PeopleFinderDepartments.txt"; > while > (<T>) {chomp;($k, $h) = split(/\t/); print "$k-- $h:\n";}' > 1-- H.07: > 2-- H.22: > 3-- H.30: > 4-- H.32: > 5-- H.32.01: > 6-- H.32.05: > 7-- H.32.06: > [EMAIL PROTECTED]: $ > > If instead of $h, I want to assign it to a hash, $h{$k} for use later, > it doesn't seem to work: > > [EMAIL PROTECTED]: $ perl -e 'open T, "/tmp/PeopleFinderDepartments.txt"; > while > (<T>) {chomp; ($k, $h{$k}) = split(/\t/); print "$k-- $h{$k}:\n";}' > 1-- : > 2-- : > 3-- : > 4-- : > 5-- : > 6-- : > 7-- : > [EMAIL PROTECTED]: $ > > What don't I understand about assigning values to a hash? What am I > overlooking?
It's not the hash that you're not understanding. It's the list assignment. List assignments happen in parellel. That is, both assignments in the expression ($foo, $bar) = (1, 2); happen at the same time. So when you try to do ($k, $h{$k}) = split("\t"); at the time $h{$k} is evaluated, $k does not yet have the value from this loop. Since you are using global variables, it still has the value from the previous loop. So you are not assigning to the proper slot in the hash. But then when you get to the print statement, by now $k *has* been updated, and you're printing out $h{$k}, meaning the "new" position in the hash, which hasn't yet been assigned to. You can verify this explanation by examining the full hash: $ cat -vet tmp.txt 1^IH.07$ 2^IH.22$ 3^IH.30$ 4^IH.32$ 5^IH.32.01$ 6^IH.32.05$ 7^IH.32.06$ $ perl -MData::Dumper -lne'($k, $h{$k}) = split /\t/; END { print Dumper(\%h) }' tmp.txt $VAR1 = { '6' => 'H.32.06', '' => 'H.07', '4' => 'H.32.01', '1' => 'H.22', '3' => 'H.32', '2' => 'H.30', '5' => 'H.32.05' }; Instead, you'll have to assign the variables independently, and only use $k after it's been assigned: $ perl -MData::Dumper -lne'($k, $v) = split /\t/; $h{$k} = $v; END { print Dumper(\%h) }' tmp.txt $VAR1 = { '6' => 'H.32.05', '4' => 'H.32', '1' => 'H.07', '3' => 'H.30', '7' => 'H.32.06', '2' => 'H.22', '5' => 'H.32.01' }; Paul Lalli P.S. In my one liners, -l simply auto-chomps and auto-appends a newline, and -n sticks a while(<>) { } block around the code. See perldoc perlrun for more details. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/