Ответ, что вам нужен оператор привязки, =~
вместо присваивания operat0r, =
, или что вам не нужно связывать переменную по умолчанию.
В последнее время я былиспользуя printf
для такого рода вещей:
while( <DATA> ) {
next if /\>/;
printf "A:%s C:%s G:%s\n", tr/A//, tr/C//, tr/G//;
}
Я часто хотел, чтобы tr///
мог интерполировать, чтобы я мог написать это, что не работает:
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $_\n";
printf "A:%s C:%s G:%s\n", map { $line =~ tr/$_// } qw(A C G);
}
Обратите внимание, что у меня было бы дополнительное раздражение при столкновении $_
, если бы я использовал переменную по умолчанию в while
.Я знаю, что мог бы сделать eval
, но это не только больше хлопот, но и l4m3:
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $_\n";
printf "A:%s C:%s G:%s\n", map { eval "\$line =~ tr/$_//" } qw(A C G);
}
Мне не нужно было знать подробности реализации, поэтому я мог бы перенести это вПодпрограмма, пока я не смогу выяснить, как избавиться от eval
, хотя дополнительные вызовы подпрограммы могут замедлить обработку больших данных:
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $line\n";
printf "A:%s C:%s G:%s\n", map { count_bases( $line, $_ ) } qw(A C G);
}
sub count_bases { eval "\$_[0] =~ tr/$_[1]//" }
Возможно, есть какой-то умный путь к строкам XOR, если вы этого не сделаетекак tr///
, но я никогда не занимался этим достаточно долго, чтобы понять это (не то, чтобы это было лучше, чем то, что вы уже делаете).