ダイナミックスコープがない言語では
再帰呼び出しのスタック間でデータを共有する場合は、以下のように仮引数を使わなければならない。*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