BioPerl に読み込んでいる系統樹があります。ツリーを出力するときにノードを垂直方向に並べ替えるために、カスタム ソート関数 (以下の「$depth_sort」) を使用したいと考えています。ただし、以下で使用される文書化された方法は、実際にソートせずに、読み込まれたのと同じ順序でツリーを書き出します。
use strict;
use Bio::TreeIO;
my $input = new Bio::TreeIO(-file=>"input.tree", -format=>'newick');
my $tree = $input->next_tree;
my $depth_sort = sub { $a->depth <=> $b->depth };
#this is the way it is supposed to work:
my $out = new Bio::TreeIO(
-file => ">sorted.tree",
-format => 'newick',
-order_by => $depth_sort
);
$out->write_tree($tree);
代わりに、ツリーを手動で繰り返し処理して、何が起こっているかを確認できます。ローカルで独自の並べ替えを行うと、期待どおりに機能します。
my $rnode = $tree->get_root_node;
&printNode($rnode);
sub printNode {
my $thisNode = shift;
#print the node identity and depth, just to keep track:
print "this is " . $thisNode->internal_id .
" with depth " . $thisNode->depth . "\n";
if (! $thisNode->is_Leaf) {
my @children = sort $depth_sort $thisNode->each_Descendent();
for my $otherNode (@children) { &printNode($otherNode); }
}
}
しかし、カスタムソートを each_Descendent に渡すと (上記の書き込み呼び出しが想定されている方法):
my @children = $thisNode->each_Descendent($depth_sort);
次に、次のメッセージで終了します。
treeFlipper.pl 行 7、行 1 で未定義の値に対してメソッド「depth」を呼び出すことはできません。
ここで、正しい軌道に乗っていると思われる別のスレッドを見つけましたが、まだ解決していません: Perl sorting; 名前空間全体で $a、$b パッケージ グローバルをきれいに処理する
最初の回答でプロトタイピング方法に切り替える:
my $depth_sort = sub ($$) {
my ($a1,$b1) = @_;
return ($a1->depth <=> $b1->depth) };
私に与えます:
treeFlipper.pl 行 9、行 1 の unblessed 参照でメソッド「depth」を呼び出せません。
しかし、参照タイプを確認すると、それは正しいようです:
print ref($a1) . "\n";
与える
Bio::Tree::Node
参照を強制的に祝福しようとすると(これはおそらくひどいことです):
bless $a1, 'Bio::Tree::Node';
bless $b1, 'Bio::Tree::Node';
私は得る:
/usr/local/share/perl/5.14.2/Bio/Tree/Node.pm の 433 行目、1 行目の HASH リファレンスではありません。
そのスレッドの他のメソッド (呼び出し元を使用) では、同じ古い「未定義の値」エラーが発生します。
これは BioPerl の問題ですか、それとも (私が推測するように) まだ何か足りないのでしょうか? ありがとう!
編集:Ubuntu 12.04 LTSでPerl 5.14.2を使用