perl子例程引用可以';得不到价值
这段代码是用来读取blast文件的,在这个子程序中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
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
,这将使代码更简单。