関数とメソッドとクロージャ

Groovyに関して少し調べた。GroovyもRubyと同様、関数という概念はどうやらないっぽい。すなわちトップレベルで定義すると関数でなくクラスのメソッドとして定義される。メソッドとクロージャだけである。また、メソッド内でメソッドを定義するのもエラーが発生してできない。

def foo() {
  println 'in foo'
  def bar() {
    println 'in bar'
  }
}

//実行結果
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Script30: 3: Unknown type: METHOD_DEF at line: 3 column: 3. File: Script30 @ line 3, column 3.
1 error

クロージャであればメソッド内で定義できる。

def foo() {
  println 'in foo'
  def bar = { println 'in bar' }
  bar()
}
foo()

//実行結果
in foo
in bar


また、インスタンスオブジェクトを通してメソッドに直接アクセスできない。プロパティとして解釈されてしまうため、恐らくメソッドはプロパティとはならないためエラーが発生する。

class Foo {
  def foo() {
    println 'in foo'
  }
}
f = new Foo()
println f.foo

//実行結果
groovy.lang.MissingPropertyException: No such property: foo for class: Foo
	at Script23.run(Script23:7)

以下のように外からメソッドにアクセスするためには「.&」で取り出す必要がある。

class Foo {
  def foo() {
    println 'in foo'
  }
}
f = new Foo()
println f.&foo

//実行結果
org.codehaus.groovy.runtime.MethodClosure@1264bf5

メソッドとクロージャは定義の方法が違うだけで、以下のようにクロージャとなっているので、メソッドの正体はクロージャと考えて良いのだろうか?

def foo() {}
def bar = {}

println this.&foo
println this.&bar

//実行結果
org.codehaus.groovy.runtime.MethodClosure@1822112
org.codehaus.groovy.runtime.MethodClosure@4957c7

Rubyもそうだと思うが、構文が複数あると混乱の元だと思う。この辺は仕方ないのかな?そのおかげで、メソッド内でメソッドが定義できないというのは非常に混乱する。GroovyもRubyの悪い点を引き継いでいると思う。