メソッドのself
最近『初めてのRuby』を読んでいる。Pythonのメソッドの第一引数にselfを書かなくてはいけないが、Rubyと対比して理由がなんとなく分かったので検討してみる。
まずPythonではRubyと同様、インスタンスメソッドとトップレベル関数の区別がない。Pythonではメソッドと関数という呼び方をする。関数およびメソッドは単なるオブジェクトの属性である。つまりメソッドはクラスオブジェクトのcallableな属性、関数はモジュールオブジェクトのcallableな属性である。Pythonでも全てがオブジェクトなので、この区別をしないということが重要となる。
ここで、以下のクラス定義を考えてみる。
>>> class Foo: ... a = 1 ... def foo(self): ... a # エラー (1) ... Foo.a # OK (2) ... self.a # OK (3) ...
クラス内に関数を定義した場合、ローカル変数(グローバル変数)、クラス変数、インスタンス変数の区別を考えなくてはならない。Rubyでは変数の頭に「何も付けない」、「@を付ける」、「@@を付ける」で構文上区別している。Pythonでは以下のようになる。
1. クラス内で関数を定義すると属性になるので、クラス内で変数を定義しても属性とする
-
- 属性なので、Foo.a のような構文で参照させる
2. 次にローカル変数(グローバル変数)とそれ以外のクラス変数、インスタンス変数を区別するため以下のようにする
3. selfをどうにかしないといけない
ここで、ポイントとしてはRubyのようにselfは省略可とした場合、インスタンス変数に特殊な構文を用意しない限り、ローカル変数とインスタンス変数の区別がつかなくなってしまう。構文上区別しなくても良いが、lookupの規則が複雑になり遅くなる。また同じ変数名が使用できないという制限も付いてしまう。なので通常は違うものであるとして区別したいので、selfを導入するしかない。
4. Rubyのような暗黙のselfはどうだったのか?