2014-05-15 25 views
-2

工作,我有以下代碼:的if/else並不在Perl

if ($strand_hit eq "-" and $strand_key ne "+") { 
    $upstream_exonic_antisense{$key} = $hit; 
} 
elsif ($strand_hit eq "-" and $strand_key eq "-") { 
    $upstream_exonic_sense{$key} = $hit; 
    print "hola\n"; 
        } 
elsif ($strand_hit eq "-" and $strand_key eq ".") { 
    $upstream_exonic_unknown{$key} = $hit; 
} 
elsif ($strand_hit eq "+" and $strand_key ne "-") { 
    $downstream_exonic_antisense{$key} = $hit; 
} 
elsif ($strand_hit eq "+" and $strand_key eq "+") { 
    $downstream_exonic_sense{$key} = $hit; 
    print "hola\n"; 
} 
elsif ($strand_hit eq "+" and $strand_key eq ".") { 
    $downstream_exonic_unknown{$key} = $hit; 
} 
elsif ($strand_hit eq ".") { 
    $updown_exonic_unknown{$key} = $hit; 
} 
else { 
    print $strand_key.$strand_hit."\n"; 
    next; 
} 

變量$strand_hit$strand_key可以+-,或.。然而,elsif(s)不工作,一切都去else聲明......你知道爲什麼嗎?

謝謝。

+5

我猜你已經從鍵盤輸入'$ strand_hit'和'$ strand_key',但是沒有'chomp'它們。請'使用Data :: Dumper; $ Data :: Dumper :: Useqq = 1;打印Dumper($ strand_hit,$ strand_key)'來診斷問題 – Borodin

+0

我建議你在if打印$ strand_hit和$ strand_key的長度之前添加一個打印語句。如:print「length fo hit:」。長度($ strand_hit)。 「關鍵字長度:」.length($ strand_key)。 「\ n」 個;如果標量不完全是1的長度,則比較將不起作用。 – Glenn

+0

length = 1 ...我應該說,如果我改變'elsif'爲一個簡單的'if'一切正常......我不知道爲什麼。 – user2886545

回答

0

除此之外,你還沒有chomped您輸入的數據,在你第一次測試的可能性,第二和第三elsifs無法執行。我懷疑其餘的測試也有類似的缺陷。

重構:

if ($strand_hit eq "-") { 
    if ($strand_key ne "+") { # should this be eq ?? 
    $upstream_exonic_antisense{$key} = $hit; 
    } elsif ($strand_key eq "-") { 
    $upstream_exonic_sense{$key} = $hit; 
    print "hola\n"; 
    } elsif ($strand_key eq ".") { 
     $upstream_exonic_unknown{$key} = $hit; 
    } 
} elsif ($strand_hit eq "+") { 
    if ($strand_key ne "-") { # should this be eq? 
    $downstream_exonic_antisense{$key} = $hit; 
    } elsif ($strand_key eq "+") { 
    $downstream_exonic_sense{$key} = $hit; 
    print "hola\n"; 
    } elsif ($strand_key eq ".") { 
    $downstream_exonic_unknown{$key} = $hit; 
    } 
} elsif ($strand_hit eq ".") { 
    $updown_exonic_unknown{$key} = $hit; 
} else { 
    print $strand_key.$strand_hit."\n"; 
    next; 
} 

讓我們假設$ strand_hit EQ ' - ' 的時刻。 如果$ strand_key eq'+'以上都不會執行if語句。第一個語句將執行所有其他值$ strand_key

現在假設$ strand_hit eq' - '。在else塊中的第一個語句是唯一可以再次執行的語句。

我建議你加入這兩個值加在一起,並有兩個字符串if語句。這將更容易閱讀。帶有和子句的多個elsifs是魔鬼的工作...

2

要麼一個或兩個變量都不是你想象的那樣(例如,在最後有一個換行符),或者代碼不會出現要工作,因爲它是錯誤的:如果if條件爲真,則第一個和第二個elsif條件也將爲真,但從未達到因爲if分支將被採用。同樣,如果第三個elsif條件是真的,第四和第五elsif分支將永遠不會被採取。你能用英文描述你期望你的代碼做什麼嗎?

2

如前所述,很可能您的變量包含諸如返回字符之類的工件。在這種情況下,通過將變量輸出到控制檯,始終調試代碼。 print "'$var'\n";

我也想向您介紹另一種方法對於這類的if/else情況。您可以創建一個派發表,該派發表根據您正在比較的值來保存要執行的匿名子例程。當您使用的代碼特別簡單時,這可能是一個有用的構造。

my %dispatch_table = (
    '-' => { 
     '+' => sub { $upstream_exonic_antisense{$key} = $hit; }, 
     '-' => sub { $upstream_exonic_sense{$key} = $hit; print "hola\n"; }, 
     '.' => sub { $upstream_exonic_unknown{$key} = $hit; }, 
     }, 
    '+' => { 
     '-' => sub { $downstream_exonic_antisense{$key} = $hit; }, 
     '+' => sub { $downstream_exonic_sense{$key} = $hit; print "hola\n"; }, 
     '.' => sub { $downstream_exonic_unknown{$key} = $hit; }, 
     }, 
    ); 

if (my $sub = $dispatch_table{$strand_hit}{$strand_key}) { 
    $sub->(); 
} 
elsif ($strand_hit eq ".") { 
    $updown_exonic_unknown{$key} = $hit; 
} 
else { 
    warn "strand_key = '$strand_key', strand_hit = '$strand_hit'\n"; 
    next; 
} 

注意我是如何隨附單引號的其他調試信息,以確保你可以看到,如果有變量內的任何工件間距。

+0

儘管我也回答了這個問題,但我更喜歡此解決方案作爲對問題更全面的解決方案 – vogomatix