I have the following code:

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;
}

The variables $strand_hit and $strand_key can be +, -, or .. However, the elsif(s) do not work and everything go to the else statement... Do you know why?

Thanks.

有帮助吗?

解决方案 3

Apart from the possibility that you have not chomped your incoming data, in your first test, the second and third elsifs cannot be executed. I suspect the rest of the tests are similarly flawed.

Refactoring:

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;
}

Lets assume $strand_hit eq '-' for the moment. If $strand_key eq '+' none of the above if statements will be executed. The first statement will be executed for all other values of $strand_key

Now assume $strand_hit eq '-'. The first statement in the block of if elses is the only one that can be executed again.

I suggest you join the two values together and have if statements for the two character string. It will be easier to read. Multiple elsifs with and clauses are the work of the devil...

其他提示

Either there is an issue with one or both of the variables not being exactly what you think (for instance, having a newline at the end), or the code doesn't appear to be working because it is buggy: If the if condition is true, the first and second elsif conditions will be true too, but never get reached because the if branch will be taken. Similarly, if the third elsif condition is true, the forth and fifth elsif branches will never be taken. Can you describe in English what you expect your code to do?

As was already stated, most likely your variables contain artifacts such as return characters. Always debug your code by printing out the variables to the console in situations like this. print "'$var'\n";

I'd also like to introduce you to another method for this type of if/else situation. You can create a dispatch table that holds anonymous subroutines to be executed based off the values you're comparing against. This can be a useful construct when the code that you're working with is especially simple, just long.

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;
}

Note how I've enclosed the else debugging message with single quotes to ensure you can see if there is any artifact spacing inside the variables.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top