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/


Reply via email to