tenacious
tenacious

Reputation: 91

Perl: Subroutines first argument is not the class

I'm relatively new to Perl so bear with me.

My sub getGenes calls getFeaturesByGeneName in the class SequenceModule. The first loop runs fine however in the second loop it tries to invoke get_SeqFeatures (a BioPerl sub) on the string $name meaning that it skips my $self = shift.

What am I missing?

sub getGenes
{
    my @names = shift;
    my $genome = shift;
    my @cds;

    foreach my $name (@names)
    {
        my $feat = SequenceModule -> getFeatureByGeneName($genome, $name);
        push (@cds, $feat);
    }

    return @cds;
}

...

sub getFeatureByGeneName
{
    my $self = shift;

    my $seq = shift;
    my $name = shift;

    my @cds = $seq -> get_SeqFeatures("CDS");

    ...
}

Upvotes: 1

Views: 69

Answers (1)

choroba
choroba

Reputation: 242208

Speculation: you called getGenes with several names:

getGenes(('name1', 'name2'), $genome);

List don't nest in Perl, so the arguments are flattened:

getGenes('name1', 'name2', $genome);

shift can't return more than one element. Therefore,

my @names = shift;

is equivalent to

my @names;
$names[0] = shift;

The second name is still in @_, so it goes to $genome:

my $genome = shift;

If you need to pass a list to a sub, make it the last argument, or send a reference:

sub getGenes {
    my $genome = shift;
    my @names = @_;
}
getGenes($genome, 'name1', 'name2');

# OR

sub getGenes {
    my $names = shift;
    my $genome = shift;
    for my $name (@$names) {  # dereference
        ...
    }
}
getGenes(['name1', 'name2'], $genome);

Upvotes: 8

Related Questions