Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:


hi, I am a beginner for perl. So forgive mysilly problem.
#!/usr/bin/perl -w use strict; my %myhash=(); my $myhash; sub do_hash { my ($filename)=@_; open(FH, $filename) or die "Can't open $filename: $!\n"; while(<FH>){ chomp; my ($Name, $Data)=split/\t/; } close FH; } open(DATA_LIST, "<data_list") or die "Can't open data_list to read!: $ +!\n"; while (<DATA_LIST>){ chomp; my ($Line,$Filed,$Dvalue)=split/\t/; #open(MYHASH, ">myhash") or die "Can't open myhash to write : $!\n"; do_hash("file_data"); print $myhash{$Line},"\n"; if (exists $myhash{$Line}){ print $Filed,"\t ",$Dvalue,"\t", $myhash{$Line},"\n"; } }

When I run it, it tell me:
Use of uninitialized value at ./dsilklx line 51.which is:
print $myhash{$Line},"\n";
if I use:
 print $myhash{a123},"\n"; instead(al23 is one of the $Line value), it print out the whole value correctlly. It print out $Line, $Filed and $Dvalue correctlly too. What is the problem? Please help!

Edit kudra, 2002-05-22 Changed title, fixed code tags

Replies are listed 'Best First'.
Re: hash problem
by vladb (Vicar) on May 21, 2002 at 15:57 UTC
    Let me reformat your code a little bit in order to make its purpose clear:
    #!/usr/bin/perl -w use strict; my %myhash=(); my $myhash; open(DATA_LIST, "<data_list") or die "Can't open data_list to read!: $ +!\n"; while (<DATA_LIST>){ chomp; my ($Line,$Filed,$Dvalue)=split/\t/; #open(MYHASH, ">myhash") or die "Can't open myhash to write : $!\n"; # vladb: reading data from file 'file_data' into %myhash hash.. do_hash("file_data"); # vladb: are you absolutely sure value stored in $Line # was also found in the 'file_data' file which was used to # initialize the %myhash hash structure? print $myhash{$Line},"\n"; # *** vladb: move this line inside the f +ollowing if(..){} block. if (exists $myhash{$Line}){ print $Filed,"\t ",$Dvalue,"\t", $myhash{$Line},"\n"; } } sub do_hash { my ($filename)=@_; open(FH, $filename) or die "Can't open $filename: $!\n"; while(<FH>){ chomp; my ($Name, $Data)=split/\t/; $myhash{$Name}=$Data; } close FH; }
    Please refer to my comments inside your code. The problem here, essentially, is that you are reading records from 'file_data' file and storing them in a global %myhash hash structure such that the first field of each record is your hash key, while the second field is your value. However, as you read records (lines) from the 'data_list' file and use the first field value (stored in the $Line) variable to reference a value in the %myhash hash, there's no absolute guarantee that the hash contains a matching key in the first place. One suggestion would be to move the print $myhash{$Line},"\n"; line inside the if block that follows. This way, you'll never attempt to access a hash record via a non-existant key.

    UPDATE: Dear, Anonymous Monk you have to absolutely check for a key to exist in a hash before actually using it to retrieve any data from that hash. Therefore, to avoid the kind of error you were getting, my suggestion would be to move the line marked with '***' inside your if block where you check for the key to 'exist' before using it...

    _____________________
    $"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+) +-.*)$/;$_=&#91"ps -e -o pid | "," $2 | "," -v "," "&#93;`@$_`?{print" ++ $1"}:{print"- $1"}&&`rm $1`;print"\n";}

      Thank you for your help!
      My first file is a table:
      Line Field Dvalue
      a123 A1 12.83
      a124 A1 9.68
      ...
      and second file is a table too:
      Name Data
      a123 acgt...(whole sequence)
      a124 catt...
      both table all use tab to separate each column. Please help!
      Thanks, If I put this line inside the following if(..){} block.: print $myhash{$Line},"\n"; it will hanging there, gives you nothing and never exit at all. which just like I do not have this line and program go directly to if (..) {} block.
Re: hash problem
by DamnDirtyApe (Curate) on May 21, 2002 at 15:54 UTC

    It's pretty difficult to call without having the input data to test against, but if $myhash{$Line} is an uninitialized, then either the regex in the do_hash function failed to assign a value to $Data, or the value of $Line in the main body regex doesn't match up to your keys. If the problem is the former, you likely have some badly-formed data in file_data. If the problem is the latter, I would guess badly-formed data in data_list.


    _______________
    D a m n D i r t y A p e
    Home Node | Email

      Thank you for your help!
      My first file is a table:
      Line Field Dvalue
      a123 A1 12.83
      a124 A1 9.68
      ...
      and second file is a table too:
      Name Data
      a123 acgt...(whole sequence)
      a124 catt...
      both table all use tab to separate each column. Please help!
      The file_data part sequence is about 4kb. acgttaga...
      I'd like to send you whole data set, would you please give me e-mail address? I test the program this morning using simple data set, it works good. Thanks
        Sure, I don't mind. It's in my sig.
        _______________
        D a m n D i r t y A p e
        Home Node | Email
Re: hash problem
by licking9Volts (Pilgrim) on May 21, 2002 at 15:57 UTC
    It looks like $Line isn't getting a value assigned to it. I think your split command should have parentheses around the regexp:
    my ($Line, $Filed, $Dvalue) = split(/\t/);
    If you're splitting a record on tabs, you might want to check if multiple tabs separate the fields. If so, you could use:
    my ($Line, $Filed, $Dvalue) = split(/\t+/);
    I'm a beginner PERL user but I hope that helps.

    Update: Changed /\t*/ to /\t+/ to avoid unexpected results. Thanks esper!

      Just one minor detail: You want to split on /\t+/ instead of /\t*/ since the * will also match 0 tabs and could split within a field (since there are 0 tabs between every pair of characters) instead of only between fields.

      Thank you for your help!
      My first file is a table:
      Line Field Dvalue
      a123 A1 12.83
      a124 A1 9.68
      ...
      and second file is a table too:
      Name Data
      a123 acgt...(whole sequence)
      a124 catt...
      both table all use tab to separate each column. Please help!
Re: hash problem
by educated_foo (Vicar) on May 21, 2002 at 16:01 UTC
    Could you include a sample of the input data as well? Otherwise it's hard to tell what's going wrong. Thanks,

    /s

      i'm gonna guess at this one...

      Anonymous Monk says:

      Thank you for your help!
      My first file is a table:
      Line Field Dvalue
      a123 A1 12.83
      a124 A1 9.68
      ...
      and second file is a table too:
      Name Data
      a123 acgt...(whole sequence)
      a124 catt...
      both table all use tab to separate each column. Please help!

      i found this just too hard to resist ;-)

      ~Particle *loves helping Anonymous Monk*