perl子例程引用可以';得不到价值

perl子例程引用可以';得不到价值,perl,Perl,这段代码是用来读取blast文件的,在这个子程序中 parse_blast($filename, \$beginning, \$ending, \@HSPs); 似乎无法通过引用获得@HSPs值,我无法找到它无法获得值的原因。所有的子程序似乎都能工作,我也可以直接在sub parse_one_HSP中打印值 use strict; use warnings; my $filename = q/..\test\input.txt/; my ($beginning, $ending); my @H

这段代码是用来读取blast文件的,在这个子程序中

parse_blast($filename, \$beginning, \$ending, \@HSPs);
似乎无法通过引用获得@HSPs值,我无法找到它无法获得值的原因。所有的子程序似乎都能工作,我也可以直接在sub parse_one_HSP中打印值

use strict;
use warnings;
my $filename = q/..\test\input.txt/;
my ($beginning, $ending);
my @HSPs;

parse_blast($filename, \$beginning, \$ending, \@HSPs); #Can't get the HSPs value
print $beginning;

foreach my $t(@HSPs){
    print_HSP(%{$t});  #can't print anything here
}
print $ending; 


sub print_HSP{
    my(%HSP)=@_;
    print "\n-> Expect value:   $HSP{expect}\n";
    print "\n-> Query string:   $HSP{query}\n";
    print "\n-> Query range:    $HSP{query_range}\n";
    print "\n-> Subject String: $HSP{subject}\n";
    print "\n-> Subject range:  $HSP{subject_range}\n";
}

sub parse_blast {
    my ($filename, $beginning_ref, $ending_ref, $HSPs) = @_;
    # parse the blast output into 3 sections
    my ($part1, $part2, $part3); # beginning, alignments and ending
    my $in_beginning = 0;
    my $in_alignment = 0;
    my $in_ending = 0;
    open IN, $filename || die;
    while (<IN>) {
        if (/^T?BLAST[NPX]/) {$in_beginning = 1}
        if (/^ALIGNMENTS/) {$in_beginning = 0; $in_alignment = 1; next}
        if (/^\s\sDatabase/) {$in_alignment = 0; $in_ending = 1;}
        if ($in_beginning) {$part1 .= $_;}
        if ($in_alignment) {$part2 .= $_;}
        if ($in_ending) {$part3 .= $_;}
    }
    close IN;

    $$beginning_ref = $part1;
    $$ending_ref = $part3;
    # split the alignments into an array
    my @alignments;
    split_alignments($part2, \@alignments);
    # parse each alignment
    foreach my $alignment (@alignments) {
        parse_one_alignment($alignment, \@$HSPs);
    }
}

sub split_alignments{
    my ($alignments, $aligns) = @_;
    my @alignment;
    while ($alignments =~ /^>.*\n(^(?!>).*\n)+/gm) {
        push @$aligns, $&;
    }
}

sub parse_one_alignment{
    my ($align, $HSPs) = @_;
    my ($part1, $part2) = $align =~ /(.*?)( Score =.*)/s;

    while ($part2 =~ /^ Score =.*\n(^(?! Score =).*\n)+/mg) {
        my %hsp;
        parse_one_HSP($part2, \%hsp);

        push @$HSPs, %hsp;
    }
}

sub parse_one_HSP {
    my ($data, $hsp) = @_;
    #my $hsp = shift; # reference to hash

    # parsing one HSP ...

    # declare and initialize variables
    my($expect) = '';
    my($query) = '';
    my($query_range) = '';
    my($subject) = '';
    my($subject_range) = '';

    ($expect) = ($data =~ /Expect = (\S+)/);

    $query = join ( '' , ($data =~ /^Query.*\n/gm) );

    $subject = join ( '' , ($data =~ /^Sbjct.*\n/gm) );

    $query_range = join('..', ($data =~ /(\d+).*\D(\d+)/s));

    $subject_range = join('..', ($data =~ /(\d+).*\D(\d+)/s));

    $query =~ s/[^acgt]//g;

    $subject =~ s/[^acgt]//g;

    $hsp->{expect} = $expect;
    $hsp->{query} = $query;
    $hsp->{query_range} = $query_range;
    $hsp->{subject} = $subject;
    $hsp->{subject_range} = $subject_range;
    #print_HSP(%$hsp);
}
使用严格;
使用警告;
我的$filename=q/。\test\input.txt/;
我的($开始,$结束);
我的@HSPs;
解析\u blast($filename,\$start,\$end,\@HSPs)#无法获取HSPs值
打印$start;
每台$t(@HSPs){
print_HSP(%{$t});#无法在此处打印任何内容
}
打印$end;
子打印单元{
我的(%HSP)=@;
打印“\n->Expect值:$HSP{Expect}\n”;
打印“\n->查询字符串:$HSP{Query}\n”;
打印“\n->查询范围:$HSP{Query\u range}\n”;
打印“\n->主题字符串:$HSP{Subject}\n”;
打印“\n->主题范围:$HSP{Subject\u range}\n”;
}
子爆炸{
我的($filename,$start\u ref,$end\u ref,$HSPs)=@;
#将blast输出解析为3个部分
我的($part1,$part2,$part3)#开始、对齐和结束
我的$in_期初=0;
我的$in_对齐=0;
我的$in_结尾=0;
在$filename | | die中打开;
而(){
如果(/^T?BLAST[NPX]/){$in_beging=1}
如果(/^ALIGNMENTS/){$in_begin=0;$in_alignment=1;next}
如果(/^\s\sDatabase/){$in_alignment=0;$in_ending=1;}
如果($在\u开头){$part1.=$\u;}
如果($in_alignment){$part2.=$\}
如果($in_end){$part3.=$\u;}
}
接近;
$$start\u ref=$part1;
$$ending\u ref=$part3;
#将路线拆分为阵列
我的@路线;
分割对齐($part2,\@对齐);
#解析每个对齐
foreach my$alignment(@alignments){
解析一个对齐($alignment,\@$HSPs);
}
}
子分割路线{
我的($alignments,$aligns)=@;
我的@alignment;
而($alignments=~/^>*\n(^(?!>).*\n)+/gm){
按@$对齐,$&;
}
}
子解析\u一个\u对齐{
我的($align,$HSPs)=@;
我的($part1,$part2)=$align=~/(.*)(分数=.*)/s;
而($part2=~/^Score=.*\n(^(?!Score=).*\n)+/mg){
我的%hsp;
解析一个HSP($part2,\%HSP);
推送@$hsp,%hsp;
}
}
子解析\u一\u热休克蛋白{
我的($data,$hsp)=@;
#my$hsp=shift;#对散列的引用
#正在分析一个热休克蛋白。。。
#声明和初始化变量
我的($expect)='';
我的($查询)='';
我的($query\u range)='';
我的($主题)='';
我的($subject\u range)='';
($expect)=($data=~/expect=(\S+/);
$query=join(“”,($data=~/^query.*\n/gm));
$subject=join(“”,($data=~/^Sbjct.*\n/gm));
$query_range=join(“..”,($data=~/(\d+).*\d(\d+)/s));
$subject_range=join('..',($data=~/(\d+).*\d(\d+)/s));
$query=~s/[^acgt]//g;
$subject=~s/[^acgt]//g;
$hsp->{expect}=$expect;
$hsp->{query}=$query;
$hsp->{query\u range}=$query\u range;
$hsp->{subject}=$subject;
$hsp->{subject\u range}=$subject\u range;
#打印HSP(%$HSP);
}

使用太多的标量和散列引用可能会导致混淆哪个变量是什么。此外,应该避免在函数参数中传递返回变量。Perl最酷的地方在于,您可以从一个函数返回多个变量,这与C不同

下面是对代码的清理。我无法测试它,因为我没有任何输入数据,但它应该按照您的预期进行:

use strict;
use warnings;

my $filename = q/..\test\input.txt/;
my ($beginning, $ending, @HSPs) = parse_blast($filename); 

print $beginning;    
foreach my $t (@HSPs){
   print_HSP($t);  #can't print anything here
}
print $ending; 

sub print_HSP{
    my($HSP) = @_;
    print "\n-> Expect value:   $HSP->{expect}\n";
    print "\n-> Query string:   $HSP->{query}\n";
    print "\n-> Query range:    $HSP->{query_range}\n";
    print "\n-> Subject String: $HSP->{subject}\n";
    print "\n-> Subject range:  $HSP->{subject_range}\n";
}

sub parse_blast {
    my ($filename) = @_;
    # parse the blast output into 3 sections
    my ($beginning, $alignments, $ending) = ("","","");
    my $in_beginning = 0;
    my $in_alignment = 0;
    my $in_ending = 0;
    open(my $IN, "<", $filename) || die;
    while (<$IN>) {
        if (/^T?BLAST[NPX]/) {
            $in_beginning = 1;
        }
        if (/^ALIGNMENTS/) {
            $in_beginning = 0;
            $in_alignment = 1;
            next;
        }
        if (/^\s\sDatabase/) {
            $in_alignment = 0;
            $in_ending = 1;
        }

        $beginning  .= $_ if $in_beginning;
        $alignments .= $_ if $in_alignment;
        $ending     .= $_ if $in_ending;
    }
    close $IN;

    # split the alignments into an array
    # and parse each alignment
    my @HSPs;
    foreach my $alignment (split_alignments($alignments)) {
        push @HSPs, parse_one_alignment($alignment);
    }
    return ($beginning, $ending, @HSPs);
}

sub split_alignments{
    my ($alignments) = @_;
    my @aligns = ($alignments =~ /^>.*\n (?: ^(?!>).*\n )+/gmx);
    return @aligns;
}

sub parse_one_alignment{
    my ($align) = @_;
    my ($part2) = $align =~ /( Score =.*)/s;

    my @HSPs;
    while ($part2 =~ /^\s Score \s =.*\n (?:^(?!\s Score \s =).*\n)+/mgx) {
        push @HSPs, parse_one_HSP($part2);
    }
    return @HSPs;
}

sub parse_one_HSP {
    my ($data) = @_;

    my ($expect) = ($data =~ /Expect = (\S+)/);

    my $query = join '' , ($data =~ /^Query.*\n/gm);
    $query =~ tr/acgt//cd;

    # FIXME "Sbjct" contains a "c"
    my $subject = join '' , ($data =~ /^Sbjct.*\n/gm);
    $subject =~ tr/acgt//cd;

    my $query_range = join '..', ($data =~ /(\d+).*\D(\d+)/s);

    my $subject_range = join '..', ($data =~ /(\d+).*\D(\d+)/s);

    return {
        expect        => $expect,
        query         => $query,
        query_range   => $query_range,
        subject       => $subject,
        subject_range => $subject_range,
    };
}
使用严格;
使用警告;
我的$filename=q/。\test\input.txt/;
my($start,$ending,@HSPs)=parse_blast($filename);
打印$start;
每台$t(@HSPs){
打印HSP($t)#无法在此处打印任何内容
}
打印$end;
子打印单元{
我的($HSP)=@;
打印“\n->Expect值:$HSP->{Expect}\n”;
打印“\n->查询字符串:$HSP->{Query}\n”;
打印“\n->查询范围:$HSP->{Query\u range}\n”;
打印“\n->主题字符串:$HSP->{Subject}\n”;
打印“\n->主题范围:$HSP->{Subject\u range}\n”;
}
子爆炸{
我的($filename)=@;
#将blast输出解析为3个部分
我的($开始,$对齐,$结束)=(“”,“”,“”);
我的$in_期初=0;
我的$in_对齐=0;
我的$in_结尾=0;

open(my$IN,“您所说的‘无法获取
@HSPs
值’是什么意思?
@HSPs
在调用parse_blast()时为空)。顺便说一句,如果您在块中缩进代码,会更容易提供帮助。此外,您的
\@$HSPs
显然是错误的。只需使用
$HSPs
在中打开,$filename | | die;
是错误的,因为
.
的绑定强度大于
。它需要写入
打开(在,$filename中)| | die;
尽管我真的建议:
打开(我的$in,'如果我是你,我可能不会尝试传递引用。我只是使用全局变量。一旦这样做有效,如果真的有必要,我可能会考虑构建一个类。你可以只使用全局变量
$start,$ending,@HSPs
,这将使代码更简单。