Groovysh 在循环中使用自定义命令
Groovysh use custom command inside loop
我有一个 groovysh 问题,我注意到您不能在循环上下文或函数内部使用 goovysh 命令。似乎命令在解析时而不是运行时进行评估。
是否有一些神奇的语法可以解决这个问题?
这是一个例子:
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>
我希望有一些方法可以通过直接引用 shell 或其他语法的其他语法来引用自定义命令。
好的,我只是想出了一个有点老套的解决方案。掌握 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
===> org.codehaus.groovy.tools.shell.Groovysh@16ec132
groovy:000> myshell = _
===> org.codehaus.groovy.tools.shell.Groovysh@16ec132
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>
添加到列表中。
我有一个 groovysh 问题,我注意到您不能在循环上下文或函数内部使用 goovysh 命令。似乎命令在解析时而不是运行时进行评估。
是否有一些神奇的语法可以解决这个问题?
这是一个例子:
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>
我希望有一些方法可以通过直接引用 shell 或其他语法的其他语法来引用自定义命令。
好的,我只是想出了一个有点老套的解决方案。掌握 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
===> org.codehaus.groovy.tools.shell.Groovysh@16ec132
groovy:000> myshell = _
===> org.codehaus.groovy.tools.shell.Groovysh@16ec132
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>
添加到列表中。