Perl中未定义的子例程和主要错误

时间:2014-11-15 15:39:54

标签: perl bioinformatics subroutine fasta

我正在尝试从这个FASTA文件中提取DNA序列到每行的指定碱基长度,比如40。

> sample dna  (This is a typical fasta header.)
agatggcggcgctgaggggtcttgggggctctaggccggccacctactgg
tttgcagcggagacgacgcatggggcctgcgcaataggagtacgctgcct
gggaggcgtgactagaagcggaagtagttgtgggcgcctttgcaaccgcc
tgggacgccgccgagtggtctgtgcaggttcgcgggtcgctggcgggggt

使用此Perl模块(fasta.pm):

package fasta;
use strict;

sub read_fasta ($filename) {
    my $filename = @_;
    open (my $FH_IN, "<", $filename) or die "Can't open file: $filename $!";
    my @lines = <$FH_IN>;
    chomp @lines;
    return @lines;
}

sub read_seq (\@lines) {
    my $linesRef = @_;
    my @lines = @{$linesRef};
    my @seq;
    foreach my $line (@lines) {
        if ($line!~ /^>/) {
            print "$line\n";
            push (@seq, $line);
        }
    }
    return @seq;
}

sub print_seq_40 (\@seq) {
    my $linesRef = @_;
    my @lines = @{$linesRef};
    my $seq;
    foreach my $line (@lines) {
        $seq = $seq.$line;
    }

    my $i= 0;
    my $seq_line;
    while (($i+1)*40 < length ($seq)) {
        my $seq_line = substr ($seq, $i*40, 40);
        print "$seq_line\n";
        $i++;
    }
    $seq_line = substr ($seq, $i*40);
    print "$seq_line\n";
}
1;

主要脚本是

use strict;
use warnings;
use fasta;

print "What is your filename: ";
my $filename = <STDIN>;
chomp $filename;

my @lines = read_fasta ($filename);
my @seq = read_seq (\@lines);
print_seq_40 (\@seq);
exit;

这是我得到的错误

Undefined subroutine &main::read_fasta called at q2.pl line 13, <STDIN> line 1.

任何人都可以告诉我哪些方面我做错了?

3 个答案:

答案 0 :(得分:2)

您需要:

  • 添加到您的模块:

    use Exporter;
    our @EXPORT = qw ( read_fasta
                       read_seq ); #etc.
    
  • 明确调用远程模块中的代码:

    fasta::read_fasta();
    
  • 显式导入模块sub:

    use fasta qw ( read_fasta );
    

另外:模块的一般约定是大写模块名称的第一个字母。

答案 1 :(得分:2)

看起来你无处可去。

我认为你选择使用模块和子程序有点奇怪,因为你只调用一次子程序,并且确实对应的代码非常少。

您的程序和模块都需要以use strictuse warnings开头,并且您不能在Perl子例程中使用这样的原型。包括许多其他错误,这更接近您需要的代码。

package Fasta;

use strict;
use warnings;
use 5.010;
use autodie;

use base 'Exporter';

our @EXPORT = qw/ read_fasta read_seq print_seq_40 /;

sub read_fasta {
  my ($filename) = @_;

  open my $fh_in, '<', $filename;
  chomp(my @lines = <$fh_in>);

  @lines;
}

sub read_seq {
  my ($lines_ref) = $_[0];

  grep { not /^>/ } @$lines_ref;
}

sub print_seq_40 {
  my ($lines_ref) = @_;

  print "$_\n" for unpack '(A40)*', join '', @$lines_ref;
}

1;

<强> q2.pl

use strict;
use warnings;

use Fasta qw/ read_fasta read_seq print_seq_40 /;

print "What is your filename: ";
my $filename = <STDIN>;
chomp $filename;

my @lines = read_fasta($filename);
my @seq = read_seq(\@lines);
print_seq_40(\@seq);

答案 2 :(得分:1)

在Perl中,如果您use fasta;,则不会自动将其所有方法导出到程序的命名空间中。请改为调用fasta :: read_fasta。

或者:使用Exporter自动导出方法或启用use Fasta qw/read_fasta/等内容。

例如:

package Fasta;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw/read_fasta read_seq read_seq40/;

使用:

use Fasta qw/read_fasta read_seq read_seq40/;

您也可以让Fasta自动导出所有方法或定义关键字以对方法进行分组,虽然后者在过去给我带来了一些问题,只有在您确定值得麻烦的情况下我才会推荐它。

如果您想使所有方法可用:

package Fasta;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw/read_fasta read_seq read_seq40/;

注意@EXPORT不是@EXPORT_OK。后者允许稍后导入它们(就像我一样),前者自动导出所有。我链接到的文档清楚地说明了这一点。

我刚注意到别的东西。你在read_fasta中将@_压平为$ filename。我不确定这是否有效。试试这个:

sub read_fasta {
   my $filename = $_[0]; # or ($filename) = @_; @_ is an array. $filename not.
}

解释问题:$filename = @_;表示:将@_(ARRAY)存储到$ filename(SCALAR)中。 Perl以这种方式执行此操作:ARRAY长度存储在$ filename中。那不是你想要的。你想要数组的第一个元素。这将是$ _ [0]。

添加了可能需要的@ISA或使用Borodir的评论。