tutorial traduccion peliculas app groovy

peliculas - groovy traduccion



Incluyendo una secuencia de comandos groovy en otro groovy (11)

He leído cómo simplemente importar un archivo groovy en otra secuencia de comandos groovy

Quiero definir funciones comunes en un archivo groovy y llamar esas funciones desde otros archivos groovy.

Entiendo que esto sería usar Groovy como un lenguaje de scripting, es decir, no necesito clases / objetos. Estoy tratando de algo como DSL que se puede hacer en Groovy. Todas las variables se afirmarán desde Java y quiero ejecutar script groovy en un shell.

¿Es esto posible? ¿Alguien puede dar algún ejemplo?


¿Qué tal tratar el script externo como una clase de Java? Basado en este artículo: https://www.jmdawson.net/blog/2014/08/18/using-functions-from-one-groovy-script-in-another/

getThing.groovy El script externo

def getThingList() { return ["thing","thin2","thing3"] }

printThing.groovy El guión principal

thing = new getThing() // new the class which represents the external script println thing.getThingList()

Resultado

$ groovy printThing.groovy [thing, thin2, thing3]


A partir de Groovy 2.2, es posible declarar una clase de script base con la nueva anotación de transformación @BaseScript AST.

Ejemplo:

archivo MainScript.groovy :

abstract class MainScript extends Script { def meaningOfLife = 42 }

archivo test.groovy :

import groovy.transform.BaseScript @BaseScript MainScript mainScript println "$meaningOfLife" //works as expected


Aquí hay un ejemplo completo de incluir un script dentro de otro.
Simplemente ejecute el archivo Testmain.groovy
Comentarios explicativos incluidos porque soy agradable así;]

Testutils.groovy

// This is the ''include file'' // Testmain.groovy will load it as an implicit class // Each method in here will become a method on the implicit class def myUtilityMethod(String msg) { println "myUtilityMethod running with: ${msg}" }

Testmain.groovy

// Run this file // evaluate implicitly creates a class based on the filename specified evaluate(new File("./Testutils.groovy")) // Safer to use ''def'' here as Groovy seems fussy about whether the filename (and therefore implicit class name) has a capital first letter def tu = new Testutils() tu.myUtilityMethod("hello world")


Creo que la mejor opción es organizar cosas de utilidad en forma de clases groovy, agregarlas a classpath y permitir que el script principal se refiera a ellas a través de la palabra clave import.

Ejemplo:

scripts / DbUtils.groovy

class DbUtils{ def save(something){...} }

scripts / script1.groovy:

import DbUtils def dbUtils = new DbUtils() def something = ''foobar'' dbUtils.save(something)

secuencia de comandos en ejecución:

cd scripts groovy -cp . script1.groovy


Después de algunas investigaciones, llegué a la conclusión de que el siguiente enfoque parece ser el mejor.

algunos / subpaquetes / Util.groovy

@GrabResolver(name = ''nexus'', root = ''https://local-nexus-server:8443/repository/maven-public'', m2Compatible = true) @Grab(''com.google.errorprone:error_prone_annotations:2.1.3'') @Grab(''com.google.guava:guava:23.0'') @GrabExclude(''com.google.errorprone:error_prone_annotations'') import com.google.common.base.Strings class Util { void msg(int a, String b, Map c) { println ''Message printed by msg method inside Util.groovy'' println "Print 5 asterisks using the Guava dependency ${Strings.repeat("*", 5)}" println "Arguments are a=$a, b=$b, c=$c" } }

ejemplo.groovy

#!/usr/bin/env groovy Class clazz = new GroovyClassLoader().parseClass("${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy" as File) GroovyObject u = clazz.newInstance() u.msg(1, ''b'', [a: ''b'', c: ''d''])

Para ejecutar el script example.groovy , agréguelo a la ruta del sistema y escriba desde cualquier directorio:

example.groovy

El script imprime:

Message printed by msg method inside Util.groovy Print 5 asterisks using the Guava dependency ***** Arguments are a=1, b=b, c=[a:b, c:d]

El ejemplo anterior se probó en el siguiente entorno: Groovy Version: 2.4.13 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux

El ejemplo demuestra lo siguiente:

  • Cómo usar una clase Util dentro de una secuencia de comandos groovy.
  • Una clase Util llama a la biblioteca de terceros de Guava incluyéndola como una dependencia de Grape ( @Grab(''com.google.guava:guava:23.0'') ).
  • La clase Util puede residir en un subdirectorio.
  • Pasar argumentos a un método dentro de la clase Util .

Comentarios / sugerencias adicionales:

  • Utilice siempre una clase groovy en lugar de groovy script para la funcionalidad reutilizable dentro de sus secuencias de comandos groovy. El ejemplo anterior usa la clase Util definida en el archivo Util.groovy. Usar scripts maravillosos para la funcionalidad reutilizable es problemático. Por ejemplo, si se usa una secuencia de comandos groovy, la clase Util debería crearse una instancia en la parte inferior de la secuencia de comandos con la new Util() , pero lo más importante es colocarla en un archivo llamado cualquier cosa que no sea Util.groovy. Consulte Scripts versus clases para obtener más detalles sobre las diferencias entre las secuencias de comandos groovy y groovy.
  • En el ejemplo anterior, utilizo la ruta "${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy" lugar de "some/subpackage/Util.groovy" . Esto garantizará que el archivo Util.groovy siempre se encuentre en relación con la ubicación del script de Groovy ( example.groovy ) y no con el directorio de trabajo actual. Por ejemplo, usar "some/subpackage/Util.groovy" daría como resultado la búsqueda en WORK_DIR/some/subpackage/Util.groovy .
  • Siga la convención de nomenclatura de la clase Java para nombrar sus guiones maravillosos. Personalmente, prefiero una pequeña desviación donde los guiones comienzan con una letra más baja en lugar de una mayúscula. Por ejemplo, myScript.groovy es un nombre de script y MyClass.groovy es un nombre de clase. Al my-script.groovy nombre a my-script.groovy se producirán errores de tiempo de ejecución en ciertos escenarios, ya que la clase resultante no tendrá un nombre de clase de Java válido.
  • En el mundo de JVM en general, la funcionalidad relevante se llama JSR 223: Scripting para Java . En groovy en particular, la funcionalidad se denomina mecanismos de integración Groovy . De hecho, se puede usar el mismo enfoque para llamar a cualquier lenguaje JVM desde Groovy o Java. Algunos ejemplos notables de tales lenguajes JVM son Groovy, Java, Scala, JRuby y JavaScript (Rhino).

Groovy no tiene una palabra clave import como los lenguajes de scripts típicos que incluirán literalmente el contenido de otro archivo (al que se alude aquí: Groovy proporciona un mecanismo de inclusión ).
Debido a su naturaleza orientada a objetos / clases, debes "jugar juegos" para hacer que cosas como esta funcionen. Una posibilidad es hacer todas sus funciones de utilidad estáticas (ya que dijo que no usan objetos) y luego realizar una importación estática en el contexto de su caparazón de ejecución. Entonces puede llamar a estos métodos como "funciones globales".
Otra posibilidad sería utilizar un objeto de enlace ( http://groovy.codehaus.org/api/groovy/lang/Binding.html ) al crear su Shell y enlazar todas las funciones que desee con los métodos (la desventaja aquí sería tener enumerar todos los métodos en el enlace, pero quizás puedas usar la reflexión). Otra solución más sería anular methodMissing(...) en el objeto delegado asignado a su caparazón que le permite básicamente hacer un despacho dinámico usando un mapa o el método que desee.

Varios de estos métodos se demuestran aquí: http://www.nextinstruction.com/blog/2012/01/08/creating-dsls-with-groovy/ . Avísame si quieres ver un ejemplo de una técnica en particular.


La forma en que hago esto es con GroovyShell .

GroovyShell shell = new GroovyShell() def Util = shell.parse(new File(''Util.groovy'')) def data = Util.fetchData()


Otra forma de hacerlo es definir las funciones en una clase groovy y analizar y agregar el archivo a la ruta de clase en tiempo de ejecución:

File sourceFile = new File("path_to_file.groovy"); Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(sourceFile); GroovyObject myObject = (GroovyObject) groovyClass.newInstance();


Para los que llegan tarde, parece que groovy ahora admite el comando :load file-path que simplemente redirige la entrada del archivo dado, por lo que ahora es trivial incluir scripts de biblioteca.

Funciona como entrada para groovysh y como una línea en un archivo cargado:
groovy:000> :load file1.groovy

file1.groovy puede contener:
:load path/to/another/file invoke_fn_from_file();


Una combinación de respuestas @grahamparks y @snowindy con un par de modificaciones es lo que funcionó para mis scripts Groovy que se ejecutan en Tomcat:

Utils.groovy

class Utils { def doSth() {...} }

MyScript.groovy:

/* import Utils --> This import does not work. The class is not even defined at this time */ Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(new File("full_path_to/Utils.groovy")); // Otherwise it assumes current dir is $CATALINA_HOME def foo = groovyClass.newInstance(); // ''def'' solves compile time errors!! foo.doSth(); // Actually works!


evaluate(new File("../tools/Tools.groovy"))

Pon eso en la parte superior de tu script. Eso traerá el contenido de un archivo groovy (simplemente reemplace el nombre del archivo entre las comillas dobles con su guión maravilloso).

Hago esto con una clase sorprendentemente llamada "Tools.groovy".