Ima Noob has asked for the wisdom of the Perl Monks concerning the following question:

Hello much smarter people than I! I have a code due tomorrow for my bioinformatics class and I'm almost done, but I keep getting the error "Can't use string "analysis" as HASH ref while strict refs in use at analysis.pm at line 17." I posted my main code (Perl-1.pl) and then my class/objects (analysis.pm). Any help would be appreciated (and fast!) It's kinda long, but I put a comment where line 17 and the problem is. Thanks # Here is Perl-1:
#!/usr/bin/perl -w use strict; use Bio::SeqIO; use analysis; my $filename=<>; my %seqhash=(); my $sequence=''; my $seqname=''; my $seq_no=0; my $stream = Bio::SeqIO->new(-file => $filename, -format => 'GenBank'); while (my $seqObj = $stream->next_seq() ) { my $seq = $seqObj->seq(); my $display_id = $seqObj->display_id; $seqhash{$sequence}=$seq; $seqhash{$seqname}=$display_id; ++$seq_no; foreach my $key (keys %seqhash) { print "\n\nSeq No.".$seq_no.":=".$seqhash{$seqname}; my $nucleotides=analysis->nucleotide_count($seqhash{seqname},$seq) +; print "Amino Acid = "; my $aminoacid=analysis->aminoanalysis($seqhash{seqname},$seq); } }
#and here is analysis.pm:
package analysis; use strict; sub new { my $class = shift; my $self = bless {}, $class; my $seqname=shift; my $sequence=shift; $self->{_seqname}=$seqname; $self->{_sequence}=$sequence; return $self; } sub nucleotide_count{ my ($self)=shift; my $seqname=$self->{_seqname}; #SOMETHING WRONG HERE! my $sequence=$self->{_sequence}; my $count_of_A=0; my $count_of_T=0; my $count_of_C=0; my $count_of_G=0; my $count_of_N=0; $self=~s/\s//g; my @seq=split(//,$self); for (my $index=0; $index<$#seq+1; $index++) { if ($seq [$index] eq 'A') { ++$count_of_A; } elsif ($seq [$index] eq 'C') { ++$count_of_C; } elsif ($seq [$index] eq 'G') { ++$count_of_G; } elsif ($seq [$index] eq 'T') { ++$count_of_T; } elsif ($seq [$index] eq 'N') { ++$count_of_N; } else { print "In your sequence, there is at least one invalid cha +racter!\n"; print "Valid characters are A(a), T(t), G(g), C(c) and N(n +).\n";} } my $GC_content=(($count_of_G+$count_of_C)/($count_of_A+$count_ +of_C+$count_of_G+$count_of_T))*100; print "\n"."A = $count_of_A\n"; print "C = $count_of_C\n"; print "G = $count_of_G\n"; print "T = $count_of_T\n"; print "N = $count_of_N\n"; print "GC content="."$GC_content"."%"."\n"; } sub aminoanalysis { my ($self)=shift; my $seqname=$self->{_seqname}; my $sequence=$self->{_sequence}; my(%genetic_code) = ( 'TCA' => 'S', # Serine 'TCC' => 'S', # Serine 'TCG' => 'S', # Serine 'TCT' => 'S', # Serine 'TTC' => 'F', # Phenylalanine 'TTT' => 'F', # Phenylalanine 'TTA' => 'L', # Leucine 'TTG' => 'L', # Leucine 'TAC' => 'Y', # Tyrosine 'TAT' => 'Y', # Tyrosine 'TAA' => '_', # Stop 'TAG' => '_', # Stop 'TGC' => 'C', # Cysteine 'TGT' => 'C', # Cysteine 'TGA' => '_', # Stop 'TGG' => 'W', # Tryptophan 'CTA' => 'L', # Leucine 'CTC' => 'L', # Leucine 'CTG' => 'L', # Leucine 'CTT' => 'L', # Leucine 'CCA' => 'P', # Proline 'CCC' => 'P', # Proline 'CCG' => 'P', # Proline 'CCT' => 'P', # Proline 'CAC' => 'H', # Histidine 'CAT' => 'H', # Histidine 'CAA' => 'Q', # Glutamine 'CAG' => 'Q', # Glutamine 'CGA' => 'R', # Arginine 'CGC' => 'R', # Arginine 'CGG' => 'R', # Arginine 'CGT' => 'R', # Arginine 'ATA' => 'I', # Isoleucine 'ATC' => 'I', # Isoleucine 'ATT' => 'I', # Isoleucine 'ATG' => 'M', # Methionine 'ACA' => 'T', # Threonine 'ACC' => 'T', # Threonine 'ACG' => 'T', # Threonine 'ACT' => 'T', # Threonine 'AAC' => 'N', # Asparagine 'AAT' => 'N', # Asparagine 'AAA' => 'K', # Lysine 'AAG' => 'K', # Lysine 'AGC' => 'S', # Serine 'AGT' => 'S', # Serine 'AGA' => 'R', # Arginine 'AGG' => 'R', # Arginine 'GTA' => 'V', # Valine 'GTC' => 'V', # Valine 'GTG' => 'V', # Valine 'GTT' => 'V', # Valine 'GCA' => 'A', # Alanine 'GCC' => 'A', # Alanine 'GCG' => 'A', # Alanine 'GCT' => 'A', # Alanine 'GAC' => 'D', # Aspartic Acid 'GAT' => 'D', # Aspartic Acid 'GAA' => 'E', # Glutamic Acid 'GAG' => 'E', # Glutamic Acid 'GGA' => 'G', # Glycine 'GGC' => 'G', # Glycine 'GGG' => 'G', # Glycine 'GGT' => 'G', # Glycine ); my @seq=split(//,$self); my $aa=''; for (my $index=0; $index<$#seq-2; $index+=3) { my $codon=$seq[$index].$seq[$index].$seq[$index+2]; $aa.= $codon; if ($aa=$genetic_code{$codon}) { print "$genetic_code{$codon}"; } else { print "_"; } } } 1;

Replies are listed 'Best First'.
Re: Problem with string as HASH ref while strict refs in use
by f00li5h (Chaplain) on Nov 07, 2008 at 00:36 UTC

    you have something like

    package Cats; sub new { bless {}, shift } # generic constructor ;) sub purring { $self = shift; $self->{key} = "foos" };

    what's happening is that you are calling that method on the package, instead of on an instance of a class...

    my $self = Cats->new; $self->pruring; # will set the key, since $_[0] is $self Cats->purring; # will treat the invocant ("Cats") as a hashref, since + $_[0] is the package name

    perlboot has more. (and yes, It is deliberate that i didn't write it in terms of your code ;)

    @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;

Re: Problem with string as HASH ref while strict refs in use
by JadeNB (Chaplain) on Nov 07, 2008 at 00:38 UTC
    Your problem is that you're calling nucleotide_count as a “class method”. More concretely, when you call a method like RECEIVER->method, the method call gets RECEIVER as its first argument. The nucleotide_count code expects an instance of class analysis (which would be a hashref), but instead it's getting the string analysis itself (which is not a hashref). To fix this, call my $thingy = analysis->new with appropriate arguments, and then use $thingy->nucleotide_count instead.

    UPDATE: Oops, sorry, f00li5h beat me to it. Incidentally, note that good practice when posting questions like this is to try to strip the code down to as small as possible an example that still exhibits your error—it's a lot easier to get someone to look at 5 lines than a full program.

Re: Problem with string as HASH ref while strict refs in use
by GrandFather (Saint) on Nov 07, 2008 at 00:41 UTC

    Somewhere before the loop you should have: my $analysis = analysis->new ($seqname, $sequence); and replace all analysis-> with $analysis->.

    Suggest to whomever wrote analysis.pm that it should use a camel case Id - strict lower case is reserved for pragmas.


    Perl reduces RSI - it saves typing