GroovyShell一个编译字符串调用另一个

GroovyShell一个编译字符串调用另一个,groovy,closures,groovyshell,Groovy,Closures,Groovyshell,如果我像这样运行GroovyScript: def gs=new GroovyShell() gs.setVariable('square',{x->x*x}) gs.evaluate("print square(10)") 它很好用。问题是我希望“Square”函数也被编译。我试过这个: def gs=new GroovyShell() gs.setVariable('square',gs.parse("{x->x*x}")) gs.evaluate("print square(

如果我像这样运行GroovyScript:

def gs=new GroovyShell()
gs.setVariable('square',{x->x*x})
gs.evaluate("print square(10)")
它很好用。问题是我希望“Square”函数也被编译。我试过这个:

def gs=new GroovyShell()
gs.setVariable('square',gs.parse("{x->x*x}"))
gs.evaluate("print square(10)")
但它不起作用,我很确定这是因为gs.parse返回的“Script”对象 它的行为不像闭包--但我不想更改第二个字符串的语法--如果我这样做了,将会有很多解决方案

有什么想法吗

编辑: 写了这篇文章之后,我意识到可以简单地连接两个字符串并解析它们一次,所以每次我想运行使用square()函数的脚本时,我都必须在脚本前面加上文本“def square(x){x*x)\n…”

我可以这样做,但它似乎有点脆弱,所以我仍然愿意接受其他答案。

非常接近

您需要使用
evaluate
而不是parse从GroovyShell获取闭包,作为变量
square
传递:

def gs=new GroovyShell()
gs.setVariable( 'square', gs.evaluate( '{ x -> x * x }' ) )
gs.evaluate( 'print square(10)' )

发现这有点酷,然后就忘乎所以了…您可以根据彼此的情况使用闭包,如下所示:

def varMap = [
  square: '{ x -> x * x }',
  pyth:   '{ x, y -> Math.sqrt( square( x ) + square( y ) ) }'
]

// Create a map of name->Closure set each into the shell 
// in turn, so later Closures can depend on earlier ones in
// the list
varMap = new GroovyShell().with { shell ->
  varMap.collectEntries { name, func ->
    // Get the closure
    def fn = shell.evaluate( func )
    // Set it into this current shell
    shell.setVariable( name, fn )
    // And return the Entry name->Closure
    [ (name): fn ]
  }
}

// Ok, this is what we want to run
def command = 'println pyth( 3, 4 )'

new GroovyShell().with { shell ->
  // Set all the vars up
  varMap.each { name, fn ->
    shell.setVariable( name, fn )
  }
  // Then run the command
  shell.evaluate( command )
}
非常接近

您需要使用
evaluate
而不是parse从GroovyShell获取闭包,作为变量
square
传递:

def gs=new GroovyShell()
gs.setVariable( 'square', gs.evaluate( '{ x -> x * x }' ) )
gs.evaluate( 'print square(10)' )

发现这有点酷,然后就忘乎所以了…您可以根据彼此的情况使用闭包,如下所示:

def varMap = [
  square: '{ x -> x * x }',
  pyth:   '{ x, y -> Math.sqrt( square( x ) + square( y ) ) }'
]

// Create a map of name->Closure set each into the shell 
// in turn, so later Closures can depend on earlier ones in
// the list
varMap = new GroovyShell().with { shell ->
  varMap.collectEntries { name, func ->
    // Get the closure
    def fn = shell.evaluate( func )
    // Set it into this current shell
    shell.setVariable( name, fn )
    // And return the Entry name->Closure
    [ (name): fn ]
  }
}

// Ok, this is what we want to run
def command = 'println pyth( 3, 4 )'

new GroovyShell().with { shell ->
  // Set all the vars up
  varMap.each { name, fn ->
    shell.setVariable( name, fn )
  }
  // Then run the command
  shell.evaluate( command )
}