ローカル変数参照ルール
上に関連した話です。
ローカル変数参照の解決は、次のルールによって決定されます。
- 外側のスコープに向かって、一番近い同名の変数を静的に探す。
- 静的に見つからない場合、toplevelオブジェクトのメンバから動的に検索される。
- toplevelに無い場合、例外が投げられる
以上です。つまり、thisを暗黙的な検索対象にはしません。
C++やRubyでは、メソッドの中では、this (Rubyではself)を暗黙的に検索するため、少々戸惑うかもしれません。
// C++ class Foo{ public: virtual void hoge(); virtual void bar(); }; void Foo::hoge(){} void Foo::bar(){ hoge(); // this->hoge(); }
// Xtal Foo : class{ hoge : method(){} foo : method(){ // ↓と書けるが、このhogeは静的にローカル変数として取得されている。 hoge(); } }
これにより、Fooが継承されてhogeがオーバーライドされたとしても、相変わらずfooメソッドの中ではFoo::hogeが呼ばれつづけることになります。デザインパターンで言う「テンプレートメソッド」にならないわけです。
これをテンプレートメソッドとして動作させたいのならば、this.hoge(); と書きます。これで動的にhogeが検索されます。
何故このような挙動になっているのでしょうか?いくつか理由があります。
- 実行速度が速くなる。
- 下底クラス実装者が予期していなかったメソッドのオーバーライドをされても大丈夫。
Rubyも上と同じような、self.をつけた時だけオーバーライド呼び出しとする、という挙動にするかどうか論議があったようです。
他の言語に言及しているところでは自分は勘違いをしている可能性があります。もし間違いがありましたら指摘していただけると嬉しいです。