プロパティとフィールドとメソッド
- nobusueの日記: Grails Code Reading 第13回資料更新しました (http://d.hatena.ne.jp/nobusue/20081128/p1)
- オブジェクトインスタンスのクラス名
- obj.class.name
- オブジェクトのプロパティ/メソッド/フィールド一覧
- obj.properties
- obj.class.methods.name
- obj.class.fields.name
- オブジェクトの文字列表現
- obj.dump()
Pythonではクラスの変数もメソッドも全て属性(オブジェクト)で区別はないが、Groovyではプロパティ、フィールド、メソッドが明確に分かれている模様。
class Foo { def foo() {} def bar() { println this.class.methods[14].class } } new Foo().bar() //実行結果 class java.lang.reflect.Method
結局、メソッドは、java.lang.reflect.Methodであり、クロージャは、org.codehaus.groovy.runtime.MethodClosureであることが分かった。一応メソッドもオブジェクトとして取得可能。「.」でアクセスできるのはプロパティとフィールドだけで、メソッドは恐らく不可能。「.&」でメソッドをアクセスするとクロージャとして取得可能。
メソッドをドットでアクセスできるようにするとプロパティと区別が付かないから、メソッドに直でアクセスできないのだろうか?「メソッド=プロパティ」として値としてクロージャを持っているとすれば問題ないような気がするけど、もっと深い問題はあるのだと思う。
そもそもJavaと互換性を持つというのはかなりの制限だとは思うが、もちろんかなりのメリットはあると思う。Groovyは互換性があることが一番の売りだというイメージあるので無理だと思うが、PyPyであればJVMコードにも変換できるので、基本的に互換性を持たせようとすると良い言語ができないのではないだろうか?昔のC++ではないが、とりあえずGroovyをBetter Javaとして使用するというのは良いかもしれない。
おまけ:
class Foo { aaa // 何も指定しないとエラー final prop1 static prop2 int prop3 def prop4 public fld1 protected fld2 private fld3 def prop5 = {} public fld4 = {} protected fld5 = {} private fld6 = {} def meth1() {} public meth2() {} protected meth3() {} private meth4() {} } def f = new Foo() println f.properties println f.class.methods.name println f.class.fields.name
クラスメンバのプロパティ、フィールド、メソッドの区別のルールは以下の通り
- public、protected、privateを指定するとフィールド(ただしメソッドは除く)
- defを指定するとプロパティ
- 何も指定しないとエラー
- final、staticは区別に影響を与えない
- int、Stringなどの型の指定は区別に影響を与えない
- 値がクロージャの場合も区別に影響を与えない
- メソッド(xxx meth() {}の形式)であれば、def、public、protected、privateの指定には関係なくメソッドとなる