AntiGMO
AntiGMO

Reputation: 1587

Can't build perl class use autoload

class Gene

package Gene;
use strict;
use Carp;
use vars qw($AUTOLOAD);

my %_ok_gene_attr = (
"id" => "string",
"name" => "string",
"chrom" => "string", # chromosome or seq id
"txtStart" => "int", # 1-based
"txtEnd" => "int" # 1-based
 );

sub new {
my ($class, %arg) = @_;
my $self = {};
$self->{_id} = $arg{id} || croak "no id";
$self->{_name} = $arg{name} || croak "no db";
$self->{_chrom} = $arg{chrom} || croak "no seq_id";
$self->{_strand} = $arg{strand} || -1;
$self->{_txStart} = $arg{txStart} || -1;
$self->{_txEnd} = $arg{txEnd} || -1;
$self->{_cdsStart} = $arg{cdsStart} || -1;
$self->{_cdsEnd} = $arg{cdsEnd} || -1;
$self->{_exonCount} = $arg{exonCount} || -1;
$self->{_exonStarts} = $arg{exonStarts} || -1;
$self->{_exonEnds} = $arg{exonEnds} || -1;
$self->{_score} = $arg{score} || -1;
$self->{_name2} = $arg{name2} || -1;
$self->{_cdsStartStat} = $arg{cdsStartStat} || -1;
$self->{_cdsEndStat} = $arg{cdsEndStat} || -1;
$self->{_exonFrames} = $arg{exonFrames} || -1;

bless($self, $class);
}


sub AUTOLOAD {
my ($self, $newvalue) = @_;
my ($operation, $attribute) = ($AUTOLOAD =~ /(get)(_\w+)$/);
unless ($operation && $attribute) {
croak "Method name $AUTOLOAD is not in the recognized form get_attribute\n";
}
unless (defined $_ok_gene_attr{$attribute}) {
croak "No such attribute '$attribute' exists in the class ", ref($self);
}
if ($operation eq 'get') {
*{$AUTOLOAD} = sub { shift->{$attribute} };
} elsif($operation eq 'set') {
*{$AUTOLOAD} = sub { shift->{$attribute} = shift };
$self->{$attribute} = $newvalue;
}
return $self->{$attribute};
}

sub DESTROY {
my($self) = @_;
$self->_decr_count( );
}

I use this class in

  open my $in, '<', q/C:\Users\Jesse\Desktop\refGene.txt/ or die "Cannot open file : $!";
while(<$in>) {

    chomp $_;
    my @temp= split(/\t/, $_);
    my $i=0;
    my $temp1= Gene->new("id" => $temp[0],"name"=>$temp[1],"chrom"=>$temp[2], "strand"=>$temp[3],"txStart"=>$temp[4], "txEnd"=>$temp[5],"cdsStart"=>$temp[6],"cdsEnd"=>$temp[7],"exonCount"=>$temp[8],"exonStarts"=>$temp[9],"exonEnds"=>$temp[10],"score"=>$temp[11],"name2"=>$temp[12],"cdsStartStat"=>$temp[13],"cdsEndStat"=>$temp[14],"exonFrames"=>$temp[15]);


}

is has a error

  (in cleanup) Method name Gene::_decr_count is not in the recognized form get_attribute

It also seems the autoload function doesn't work when i use $temp1->set_id("1234")?

Upvotes: 0

Views: 61

Answers (1)

Lee Duhem
Lee Duhem

Reputation: 15121

Try this some kind of fixed version of Gene.pm:

package Gene;
use strict;
use Carp;
use vars qw($AUTOLOAD);

use Data::Dumper;

my %_ok_gene_attr = (
    "_id" => "string",
    "_name" => "string",
    "_chrom" => "string", # chromosome or seq id
    "_txtStart" => "int", # 1-based
    "_txtEnd" => "int" # 1-based
);

sub new {
    my ($class, %arg) = @_;
    my $self = {};
    $self->{_id} = $arg{id} || croak "no id";
    $self->{_name} = $arg{name} || croak "no db";
    $self->{_chrom} = $arg{chrom} || croak "no seq_id";
    $self->{_strand} = $arg{strand} || -1;
    $self->{_txStart} = $arg{txStart} || -1;
    $self->{_txEnd} = $arg{txEnd} || -1;
    $self->{_cdsStart} = $arg{cdsStart} || -1;
    $self->{_cdsEnd} = $arg{cdsEnd} || -1;
    $self->{_exonCount} = $arg{exonCount} || -1;
    $self->{_exonStarts} = $arg{exonStarts} || -1;
    $self->{_exonEnds} = $arg{exonEnds} || -1;
    $self->{_score} = $arg{score} || -1;
    $self->{_name2} = $arg{name2} || -1;
    $self->{_cdsStartStat} = $arg{cdsStartStat} || -1;
    $self->{_cdsEndStat} = $arg{cdsEndStat} || -1;
    $self->{_exonFrames} = $arg{exonFrames} || -1;

    bless($self, $class);
}


sub AUTOLOAD {
    my ($self, $newvalue) = @_;
    my ($operation, $attribute) = ($AUTOLOAD =~ /(get|set)(_\w+)$/);
    unless ($operation && $attribute) {
        croak "Method name $AUTOLOAD is not in the recognized form set_{attribute} or get_{attribute}\n";
    }
    unless (defined $_ok_gene_attr{$attribute}) {
        croak "No such attribute '$attribute' exists in the class ", ref($self);
    }
    if ($operation eq 'get') {
        no strict 'refs';
        *{$AUTOLOAD} = sub { shift->{$attribute} };
    } elsif($operation eq 'set') {
        no strict 'refs';
        *{$AUTOLOAD} = sub { shift->{$attribute} = shift };
        $self->{$attribute} = $newvalue;
    }
    return $self->{$attribute};
}

sub DESTROY {
    my($self) = @_;
    $self->_decr_count( );
}

Tested with the following script:

#!/usr/bin/perl

use strict;
use warnings;

use Gene;

my $t1 = Gene->new(id=>"id", name=>"name", chrom=>"chrom");

$t1->set_id("1234");
print $t1->get_id(), "\n";

Beside using Perl's builtin OO system, you may also want to take a look of some other OO system, such as Moose. See perlootut for further details.

Upvotes: 1

Related Questions