1

このように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」オブジェクトがクロージャーのように機能しないためだと確信しています。ただし、2番目の文字列の構文を変更したくない場合は私はたくさんの解決策があるだろうと思いました...

何か案は?

編集:これを書いた後、2つの文字列を単純に連結して一度解析することが可能であることに気付きました。そのため、square()関数を使用するスクリプトを実行するたびに、「defsquare」というテキストを先頭に追加する必要があります。 (x){x * x)\n"スクリプトに..

私はこれを行うことができますが、それは少し薄っぺらなように見えるので、私はまだ他の答えを受け入れています。

4

1 に答える 1

1

とても近い!

evaluateGroovyShellからClosureを取得して変数として渡すには、解析ではなくを使用する必要があります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 )
}
于 2012-10-29T23:24:16.080 に答える