Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call top level function from groovy method

Tags:

groovy

I figure this has a simple answer, but my web searching couldn't find it.

If I've got the following (ideone):

def f() {}

class C
{
    public h() { f() }
}

x = (new C()).h();

This fails with the following error:

No signature of method: c.f() is applicable for argument types: () values: []

How do I call f() from inside a method of C?

like image 555
Clinton Avatar asked Jul 15 '13 09:07

Clinton


3 Answers

You need a reference to the "outer" class (which isn't really an outer class).

Assuming you are writing your code in a Script.groovy file, it generates two classes: C.class and Script.class. There is no way to the C call the f() method, since it has no idea where it is defined.

You have some options:

1) @MichaelEaster's idea, giving a metaclass defition from the current scope (i.e. Script)

2) Create/pass a Script object inside C:

def f() { "f" }

class C
{
    public h(s = new Script()) { s.f() }
}

assert "f" == new C().h()

3) Make C an inner class (which also needs an instance of Script:

class Script {
  def f() { "f" }

  class C
  {
      public h() { f() }
  }

  static main(args) {
    assert "f" == new C(new Script()).h()
  }
}

4) Static inner class plus static f():

class Script {
  static def f() { "f" }

  static class C
  {
      public h() { f() }
  }

  static main(args) {
    assert "f" == new C().h()
  }
}
like image 108
Will Avatar answered Nov 15 '22 18:11

Will


Another way, without using metaClass is to define h() as a closure and use:

def f() {}
class C {     
   def h = { f() } 
}  
x = (new C()).h
x.delegate = this

x()
like image 34
dmahapatro Avatar answered Nov 15 '22 17:11

dmahapatro


Here is one way to do it, using meta-programming:

def f() {  println "Hello" }

class C
{
    public h() { f() }
}

C.metaClass.f = { f() }

x = (new C()).h();
like image 1
Michael Easter Avatar answered Nov 15 '22 18:11

Michael Easter