ダイナミックスコープがない言語では
再帰呼び出しのスタック間でデータを共有する場合は、以下のように仮引数を使わなければならない。*1
JavaScript で木構造の探索をして、依存関係を直列に並べる例
function search(node, results, seen) {
if(!results) results = [];
if(!seen) seen = {};
for(var i = 0; i < node.childs.length; i ++)
search(node.childs[i], results, seen);
if(!seen[node.name]){
results.push(node); seen[node.name]=1;
}
return results;
}
var results = search(rootNode);
Perl では
ダイナミックスコープ(local)が使えるので、以下のように local でデータが共有できる。
ちなみに、ダイナミックスコープとは呼出元の変数を呼出先で参照できるようなスコープ。レキシカルスコープとは違う。
Perl で木構造の探索して、依存関係を直列に並べる例
# package が Hoge の場合
sub search {
my $node = shift;
local $Hoge::results = $Hoge::results || [];
local $Hoge::seen = $Hoge::seen || {};
search($_) for(@{$node->childs});
push(@{$Hoge::results}, $node) unless($Hoge::seen->{$node->name}++);
return @{$Hoge::results};
}
my @results = search($root_node);
便利じゃない?
いや、便利かと思ったけど、よく見てみるとどっちもそんなに変わらないかもw まあ、local の使い方の勉強がてらに書いてみました。
いやー、Perlむずいわー。まだまだ、Perl ハッカーへの道は険しい。
*1:JSの場合は実はcalleeでもデータ共有できますがw