2017-05-24 55 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>添加到列表中來完成此操作。