AS3S.ORG

ACTIONSCRIPT 3.0 SOURCES

メソッドクロージャとバインドメソッド

「メソッドクロージャ」という用語の使われ方が混乱しているようなので詳しく調べてみました。


Adobe LiveDocsによると、メソッドクロージャは以下のように説明されています。

“メソッドクロージャ” は、関数の静的なスナップショットとその “レキシカル環境”を含むオブジェクトです。関数のレキシカル環境には、関数のスコープチェーン内のすべての変数、プロパティ、メソッド、およびオブジェクトがその値と共に含まれます。メソッドクロージャは、オブジェクトまたはクラスとは別に、関数が実行されるたびに作成されます。メソッドクロージャはそのメソッドクロージャが定義されたスコープを保持することから、関数がパラメータまたは戻り値として別のスコープに渡されると興味深い結果が生まれます。
(中略)
メソッドクロージャとバインドメソッドの主な違いは、バインドメソッドの this キーワードの値は常に最初に関連付けられたインスタンスを参照しますが、メソッドクロージャでは this キーワードの値が変更可能という点です。

要は、

public var func:Function = function():void {
   trace(this);
};

という書き方のことで、呼び出された状況によってthisが指すものが変わります。

対して、同じくAdobe LiveDocsによるバインドメソッドの説明は以下の通りです。

バインドメソッドは、メソッドクロージャとも呼ばれる、単にインスタンスから抽出されるメソッドです。バインドメソッドの例には、関数にパラメータとして渡され、関数から値として返されるメソッドがあります。ActionScript 3.0で新しく導入されたバインドメソッドは、インスタンスから抽出されたときでもレキシカル環境が保持されるメソッドクロージャに似ています。バインドメソッドとメソッドクロージャの主な違いは、バインドメソッドの this参照は、バインドメソッドを実装するインスタンスにリンクされたまま、つまりバインドされたままであるという点です。これは、バインドメソッドのthis 参照が、常にこのメソッドを実装する元のオブジェクトを指していることを意味します。メソッドクロージャの場合、this参照は汎用的で、呼び出されたときにこの関数が関連付けられているオブジェクトを指します。

要は、

public function func():void {
   trace(this);
};

という書き方のことで、こちらは常にthisはこの定義のある場所を指します。

しかし、見過ごせないのが、

バインドメソッドは、メソッドクロージャとも呼ばれる

という部分。バインドメソッド=メソッドクロージャ?その後の説明では違うと言っているのに?
こういう場合はまず原典をあたるべし、ということでそれぞれの英語版を見ると疑問が解決しました。

Function closures

A function closure is an object that contains a snapshot of a function and its lexical environment. A function’s lexical environment includes all the variables, properties, methods, and objects in the function’s scope chain, along with their values. Function closures are created any time a function is executed apart from an object or a class. The fact that function closures retain the scope in which they were defined creates interesting results when a function is passed as an argument or a return value into a different scope.

The main difference between a function closure and a bound method is that the value of the this keyword in a bound method always refers to the instance to which it was originally attached, whereas in a function closure the value of the this keyword can change.

Bound methods

A bound method, sometimes called a method closure, is simply a method that is extracted from its instance. Examples of bound methods include methods that are passed as arguments to a function or returned as values from a function. New in ActionScript 3.0, a bound method is similar to a function closure in that it retains its lexical environment even when extracted from its instance. The key difference, however, between a bound method and a function closure is that the this reference for a bound method remains linked, or bound, to the instance that implements the method. In other words, the this reference in a bound method always points to the original object that implemented the method. For function closures, the this reference is generic, which means that it points to whatever object the function is associated with at the time it is invoked.

というわけで、method closure も function closure も「メソッドクロージャ」と訳されてしまっていることが混乱のもとのようです。ここは、

function closure → ファンクションクロージャ または 関数クロージャ
bound method → バインドメソッド = method closure → メソッドクロージャ

とするのが正解な気がします。

実際に、Adobeの記事でもバインドメソッドという意味でmethod closureが使われています。
なぜ、Function closuresを「メソッドクロージャ」と訳してしまったんでしょうか?

LiveDocsにもコメント入れてみました。

Written by admin

January 24th, 2008 at 5:02 pm

Posted in misc.

Leave a Reply