2017-05-24 27 views
0

我有一个groovysh问题,我注意到你不能在循环上下文或函数内部使用goovysh命令。看起来,这些命令在解析时间而不是运行时进行评估。Groovysh在循环内使用自定义命令

是否有一些神奇的语法来解决这个问题?

下面是这样一个例子:

import org.codehaus.groovy.tools.shell.CommandSupport 
import org.codehaus.groovy.tools.shell.Groovysh 

class Rand extends CommandSupport { 
    private Random random = new Random() 

    protected Rand(final Groovysh shell) { 
     super(shell, 'rand', 'r') 
    } 

    public Integer execute(List args) { 
     random.nextInt() 
    } 

} 

:register Rand 

(1..3).each { 
    println "number ${it}" 
    rand 
    foo = _ 
    println "Random number is ${foo}" 
} 

执行时你看到的随机数不改变,你可以看到,它评估的时候我将代码粘贴到控制台,但在此之前它通过循环去:

Groovy Shell (2.4.11, JVM: 1.8.0_51) 
Type ':help' or ':h' for help. 
----------------------------------------------------------------------------------------------------------------------- 
groovy:000> import org.codehaus.groovy.tools.shell.CommandSupport 
===> org.codehaus.groovy.tools.shell.CommandSupport 
groovy:000> import org.codehaus.groovy.tools.shell.Groovysh 
===> org.codehaus.groovy.tools.shell.CommandSupport, org.codehaus.groovy.tools.shell.Groovysh 
groovy:000> 
groovy:000> class Rand extends CommandSupport { 
groovy:001>  private Random random = new Random() 
groovy:002> 
groovy:002>  protected Rand(final Groovysh shell) { 
groovy:003>   super(shell, 'rand', 'r') 
groovy:004>  } 
groovy:005> 
groovy:005>  public Integer execute(List args) { 
groovy:006>   random.nextInt() 
groovy:007>  } 
groovy:008> 
groovy:008> } 
===> true 
groovy:000> 
groovy:000> :register Rand 
===> true 
groovy:000> 
groovy:000> (1..3).each { 
groovy:001>  println "number ${it}" 
groovy:002>  rand 
===> -1321819102 
groovy:002>  foo = _ 
groovy:003>  println "Random number is ${foo}" 
groovy:004> } 
number 1 
Random number is -1321819102 
number 2 
Random number is -1321819102 
number 3 
Random number is -1321819102 
===> [1, 2, 3] 
groovy:000> 

我希望有一些方法通过直接引用外壳什么的一些其他的语法来引用自定义命令。

回答

0

好吧,我刚想出了一个hacky解决方案。获取Groovysh实例的保持装置,当我觉得喜欢它,我可以评价:

import org.codehaus.groovy.tools.shell.CommandSupport 
import org.codehaus.groovy.tools.shell.Groovysh 

class Rand extends CommandSupport { 
    private Random random = new Random() 

    protected Rand(final Groovysh shell) { 
     super(shell, 'rand', 'r') 
    } 

    public Integer execute(List args) { 
     random.nextInt() 
    } 

} 

:register Rand 

class Shell extends CommandSupport { 

    private Groovysh shellint 

    protected Shell(final Groovysh shell) { 
     super(shell, 'shell', 's') 
     shellint = shell 
    } 

    public Groovysh execute(List args) { 
     shellint 
    } 

} 

:register Shell 

shell 
myshell = _ 

(1..3).each { 
    println "number ${it}" 
    foo = myshell.execute("rand") 
    println "Random number is ${foo}" 
} 

随着输出:

Groovy Shell (2.4.11, JVM: 1.8.0_51) 
Type ':help' or ':h' for help. 
----------------------------------------------------------------------------------------------------------------------- 
groovy:000> import org.codehaus.groovy.tools.shell.CommandSupport 
===> org.codehaus.groovy.tools.shell.CommandSupport 
groovy:000> import org.codehaus.groovy.tools.shell.Groovysh 
===> org.codehaus.groovy.tools.shell.CommandSupport, org.codehaus.groovy.tools.shell.Groovysh 
groovy:000> 
groovy:000> class Rand extends CommandSupport { 
groovy:001>  private Random random = new Random() 
groovy:002> 
groovy:002>  protected Rand(final Groovysh shell) { 
groovy:003>   super(shell, 'rand', 'r') 
groovy:004>  } 
groovy:005> 
groovy:005>  public Integer execute(List args) { 
groovy:006>   random.nextInt() 
groovy:007>  } 
groovy:008> 
groovy:008> } 
===> true 
groovy:000> 
groovy:000> :register Rand 
===> true 
groovy:000> 
groovy:000> class Shell extends CommandSupport { 
groovy:001> 
groovy:001>  private Groovysh shellint 
groovy:002> 
groovy:002>  protected Shell(final Groovysh shell) { 
groovy:003>   super(shell, 'shell', 's') 
groovy:004>   shellint = shell 
groovy:005>  } 
groovy:006> 
groovy:006>  public Groovysh execute(List args) { 
groovy:007>   shellint 
groovy:008>  } 
groovy:009> 
groovy:009> } 
===> true 
groovy:000> 
groovy:000> :register Shell 
===> true 
groovy:000> 
groovy:000> shell 
===> [email protected] 
groovy:000> myshell = _ 
===> [email protected] 
groovy:000> 
groovy:000> (1..3).each { 
groovy:001>  println "number ${it}" 
groovy:002>  foo = myshell.execute("rand") 
groovy:003>  println "Random number is ${foo}" 
groovy:004> } 
number 1 
===> -666149132 
Random number is -666149132 
number 2 
===> -1675600826 
Random number is -1675600826 
number 3 
===> 412144734 
Random number is 412144734 
===> [1, 2, 3] 

是否有另一种方式做到这一点?在我需要这样的背景下,groovysh是一个定制一个带 :register去除

我体改的groovysh JAR文件早在加入:register命令,然后我可以使用上面的解决方案。我通过查看https://github.com/groovy/groovy-core/blob/master/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy并看到org/codehaus/groovy/tools/shell/commands.xml包含命令列表,并将<command>org.codehaus.groovy.tools.shell.commands.RegisterCommand</command>添加到列表中来完成此操作。