Hash ref, but what is the key? with Chemistry::File::SDF mod

P

pistachio

Hello all,

It's a ref question. I'm not getting what I'm doing wrong here. All
the other variables work but the sdf variable. When I try to print
that it just gives me an error. I've used data dumper to see what's
going on and now I'm really confused. Any help would be great.

Cheers,
PB

Abstract code below.

my $sdffile="SDF_database_file.sdf";
my @mols = Chemistry::Mol->read($sdffile);
for loop{
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");

#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";

print "$mass[$i] $name[$i] $formula[$i] $owner $date\n";
}
print $sdf[1] ."\n";
print Dumper $sdf[2] . "\n";

This gives:
517.270898 Choloyl-taurine C25H43NO8S dwong 2007-05-16 12:01:59
483.301819 Taurolithocholate C26H45NO5S dwong 2007-05-16 12:01:59
499.296729 Taurodeoxycholate C26H45NO6S dwong 2007-05-16 12:01:59
499.296729 Taurochenodeoxycholate C26H45NO6S dwong 2007-05-16
12:01:59
410.391251 hop-22(29)-ene C30H50 dwong 2007-05-16 12:01:59
HASH(0x84f45c8)
$VAR1 = 'HASH(0x84e6738)
';

Which I have no idea how to get my data from that. :D again thx for
any help.
 
P

Paul Lalli

It's a ref question. I'm not getting what I'm doing wrong here. All
the other variables work but the sdf variable. When I try to print
that it just gives me an error. I've used data dumper to see what's
going on and now I'm really confused. Any help would be great.
Abstract code below.

Abstract is massively not good enough. You're doing something wrong in
your real code that you're not doing in this code. Pare your problem
down to the shortest complete script that demonstrates the error.

But before you post again, read:
perldoc -q quoting

Paul Lalli
 
P

pistachio

This is the entire code.
Paul THX for the perldoc, will do in future :)
#usr/bin/perl -w
use strict;
use DBI();
use Chemistry::File::SDF;
use Data::Dumper;

#-----Globals-----
my (@sdf);
my $owner="xxxxx";
my $date= "2007-05-16 12:01:59";
#-----Reading Data file-----
my $sdffile="LMSDFDownload_cp.sdf";
my @mols = Chemistry::Mol->read($sdffile);

my (@sdf, @mass, @name, @formula, @keggID, @note, @ID, @mol,
@other)=0;
for (my $i=0; $i < @mols; $i++){
#print $i;
$ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};
$name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");
#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
#print ".";
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";
}
print $sdf[1] ."\n";
print Dumper $sdf[2] . "\n";
 
P

pistachio

This is the entire code.
Paul THX for the perldoc, will do in future :)
#usr/bin/perl -w
use strict;
use DBI();
use Chemistry::File::SDF;
use Data::Dumper;

#-----Globals-----
my (@sdf);
my $owner="xxxxx";
my $date= "2007-05-16 12:01:59";
#-----Reading Data file-----
my $sdffile="LMSDFDownload_cp.sdf";
my @mols = Chemistry::Mol->read($sdffile);

my (@sdf, @mass, @name, @formula, @keggID, @note, @ID, @mol,
@other)=0;
for (my $i=0; $i < @mols; $i++){
#print $i;
$ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};
$name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");
#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
#print ".";
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";
}
print $sdf[1] ."\n";
print Dumper $sdf[2] . "\n";
 
P

pistachio

This is the entire code.
Paul THX for the perldoc, will do in future :)
#usr/bin/perl -w
use strict;
use DBI();
use Chemistry::File::SDF;
use Data::Dumper;

#-----Globals-----
my (@sdf);
my $owner="xxxxx";
my $date= "2007-05-16 12:01:59";
#-----Reading Data file-----
my $sdffile="LMSDFDownload_cp.sdf";
my @mols = Chemistry::Mol->read($sdffile);

my (@sdf, @mass, @name, @formula, @keggID, @note, @ID, @mol,
@other)=0;
for (my $i=0; $i < @mols; $i++){
#print $i;
$ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};
$name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");
#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
#print ".";
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";
}
print $sdf[1] ."\n";
print Dumper $sdf[2] . "\n";
 
P

pistachio

This is the entire code.
Paul THX for the perldoc, will do in future :)
#usr/bin/perl -w
use strict;
use DBI();
use Chemistry::File::SDF;
use Data::Dumper;

#-----Globals-----
my (@sdf);
my $owner="xxxxx";
my $date= "2007-05-16 12:01:59";
#-----Reading Data file-----
my $sdffile="LMSDFDownload_cp.sdf";
my @mols = Chemistry::Mol->read($sdffile);

my (@sdf, @mass, @name, @formula, @keggID, @note, @ID, @mol,
@other)=0;
for (my $i=0; $i < @mols; $i++){
#print $i;
$ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};
$name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");
#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
#print ".";
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";
}
print $sdf[1] ."\n";
print Dumper $sdf[2] . "\n";
 
U

Uri Guttman

p> #-----Globals-----

those are not globals but file lexicals. they don't exist in the symbol table

p> my (@sdf);

why the parens?

p> my (@sdf, @mass, @name, @formula, @keggID, @note, @ID, @mol,
p> @other)=0;

that doesn't do what you think it does. first off you redeclared
@sdf. then @sdf will get assigned a 0 as its first element. the rest of
the arrays will be empty.

p> for (my $i=0; $i < @mols; $i++){

no need for that as you can loop over @mols directly and use a hash for
the other parts. this also means you can drop all of those arrays. you
have a parallel set of arrays which means you should be using an array
of hashes instead.

foreach my $mol ( @mols ) {

my %stuff ;

p> $ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};

$stuff{id} = $mol->attr("sdf/data")->{LM_ID};

isn't that much easier to read? none of those ugly [$i] in the way.

p> $name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
p> $formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
p> $mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};

do the same for those

p> my @smile;

you don't use that array

p> $sdf[$i]=$mols[$i]->attr("sdf/data");
p> #my $temp={$sdf[$i]};
p> #$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
p> #print ".";
p> print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";

print join( '', @stuff{ qw( mass name formula date id ) } ), "\n" ;

uri
 
P

Peter J. Holzer

p> for (my $i=0; $i < @mols; $i++){

no need for that as you can loop over @mols directly and use a hash for
the other parts. this also means you can drop all of those arrays. you
have a parallel set of arrays which means you should be using an array
of hashes instead.

foreach my $mol ( @mols ) {

my %stuff ;

p> $ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};

$stuff{id} = $mol->attr("sdf/data")->{LM_ID};

That hash exists only inside the loop. He could get the same effect by
just using scalar variables $ID, $name, etc.

I assume that he is filling all those arrays with values because he
intends to use them after the loop. So either he needs to keep the loop
counter (which is best if he needs to keep the correspondence to @mols)
or he can use another unique id. If LM_ID is unique and suitable for the
purpose something like :

$id = $mols[$i]->attr("sdf/data")->{LM_ID};
$stuff{$id}{name} = $mols[$i]->attr("sdf/data")->{COMMON_NAME};
$stuff{$id}{formula} = $mols[$i]->attr("sdf/data")->{FORMULA};
...

would work.

However, none of that seems to have anything to do with the OP's
problem.

hp
 
P

Peter J. Holzer

On 2007-07-11 03:47 said:
for (my $i=0; $i < @mols; $i++){
#print $i;
$ID[$i]= $mols[$i]->attr("sdf/data")->{LM_ID};
$name[$i]=$mols[$i]->attr("sdf/data")->{COMMON_NAME};
$formula[$i]=$mols[$i]->attr("sdf/data")->{FORMULA};
$mass[$i]=$mols[$i]->attr("sdf/data")->{EXACT_MASS};
my @smile;
$sdf[$i]=$mols[$i]->attr("sdf/data");
#my $temp={$sdf[$i]};
#$sdf[$i]=$mols[$i]->attr("sdf/data")->{SDF} . "\t";
#print ".";
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";
}
print $sdf[1] ."\n";

I assume this line is the problem? Please be more explicit in the
future. It is hard to answer questions if you don't know what the
question is.

At this point $sdf[1] contains the return value from
$mols[1]->attr("sdf/data"), which (judging from the code above) is a
hashref which contains at least the keys LM_ID, COMMON_NAME, FORMULA and
EXACT_MASS.

You cannot print a hashref directly, you need to print it's individual
components, e.g.,

print $sdf[1]{EXACT_MASS}, " ",
$sdf[1]{COMMON_NAME}, " ",
$sdf[1]{FORMULA}, " ",
$sdf[1]{LM_ID}, "\n";

or use a module which returns a suitable string representation, like
Data::Dumper ...
print Dumper $sdf[2] . "\n";

.... but you did that already.

hp
 
P

Paul Lalli

$sdf[$i]=$mols[$i]->attr("sdf/data");

Here you assign $sdf[$i] to be a hashref that's returned from the
attr() method.
print $mass[$i] . $name[$i] . $formula[$i] . $date . $ID[$i]. "\n";}

print $sdf[1] ."\n";

Here you attempt to print out the hashref, concatenated to the
newline. Both of those operations "stringify" the hashref. It is no
longer a reference. It is just a string that contains the word HASH
followed by a memory location.
print Dumper $sdf[2] . "\n";

Here you are attempting to print out a Dump of the hashref, but you
made the mistake of using the hashref in a concatenation. That
stringified the hashref, turning it into that "HASH(0x1234556)"
string, and then you dumped that string.

You seem to be concatenation-happy. Stop it. :p

print Dumper($sdf[2]);

If for some reason you want an extra newline at the end of your
output, print it after the dump:

print Dumper($sdf[2]), "\n";
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top