سؤال

If I run a GroovyScript like this:

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

It works just fine. The problem is that I want the "Square" function to also be compiled. I've tried this:

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

but it doesn't work, I'm pretty sure it's because the "Script" object returned by gs.parse doesn't act like a closure--but I don't want to change the syntax of the second string--If I did there would be plenty of solutions...

Any ideas?

EDIT: After writing this I realized that it would be possible to simply concatenate the two strings and parse them once, so every time I wanted to run a script that uses the square() function I'd have to prepend the text "def square(x){x*x)\n" to the script...

I can do this but it seems a little flakey so I'm still open to other answers.

هل كانت مفيدة؟

المحلول

Very close!

You need to use evaluate rather than parse to get a Closure back from the GroovyShell to pass as the variable square:

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

Found this kinda cool, and got carried away... You can have closures depending on each other like so:

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 )
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top