Gracias por compartir tu experiencia Heloisa... mucha gente no sabe que tiene la posibilidad de decidir el formato de los objetos JSON... y que puede predefinir distintos formatos de exportación e importación y utilizar uno u otro según necesite.

Duda... las clases de las que quieres exportar objetos en JSON, ¿no deberían heredar de %JSON.Adaptor? O es que consigues hacerlo de otro modo?

Muy ingenioso. Gracias por compartir!

Me ha gustado cómo le sacas partido a las funciones de asignación dinámica tanto de métodos ( $classmethod(clase,metodo)), como de propiedades ( $property(objRef,propName)). Igualmente el utilizar las macros del sistema $$$comMemberNext y $$$cCLASSproperty. 

Como sugerencia, en lugar de utilizar directamente estas macros, quizá ahí sería mejor utilizar el API que ya existe en %SYSTEM.Dictionary. En concreto esa línea podría ser:

set prop = $system.Dictionary.comMemberNext(claseRequest,$$$cCLASSproperty,prop)

Yo creo que en el Kahoot hubo hasta codazos!! laugh  La verdad es que estuvo genial poder compartir experiencias y sobre todo vernos después de casi 3 años... y las exposiciones super interesantes... personalmente me quedé con ganas de más... y los que exponían ya ni hablamos (David Cano y Carlos Fernández de Roche y Florencio López y Mario del Pozo por Arisnova)... yo creo que si no los paran aún seguían. laughlaugh  Estuvo genial. A ver si repetimos.

Seguro que hay todavía mucho %ZEN.proxyObject por ahí. ¡¡Nunca es tarde si la dicha es buena!! wink

La única precaución es que %ZEN.proxyObject es una clase de sistema... Si la modificamos, hay que preservarla en las actualizaciones y validar que no haya cambiado o hacer un merge... de otro modo perderemos los cambios nuestros o las correcciones de producto.

Por "IRIS-izarlo" un poco... aunque no tan automático como lo que presentas, podemos también alterar temporalmente los tipos en los %Library.DynamicObject.

set obj = {}
set objB = {}

set objB.phone = 961000000

set obj.phone = 91001001
set obj.nombre = "Luis"
set obj.objetoB = objB

set orig = obj.%GetSerial() //si queremos preservar el valor original
do obj.%Set("phone",obj.phone,"string")
do objB.%Set("phone",objB.phone,"string")

do obj.%ToJSON()

set obj = obj.%SetSerial(orig)  //para volver al objeto JSON original
do obj.%ToJSON()

Resultado:

{"phone":"91001001","nombre":"Luis","objetoB":{"phone":"961000000"}}
{"phone":91001001,"nombre":"Luis","objetoB":{"phone":961000000}}

Igual sería interesante ver todas las posibilidades de formateo de las antiguas clases %ZEN y ver si están cubiertas por %Dynamic*, %JSON.Adaptor y %JSON.Formatter,... y, si no,... pues igual toca funcionalidad nueva en OpenExchange! :laugh

Prueba esto:

ClassMethod Indirection()

{
    set TABLES(0)="EVEN"
    set TABLES(1)="ODD"
    for i=1:1:100
    {
        set table = TABLES((i#2))
        set @table@(i)=i 
    }

    zw @table
    set evenTotal=0
    set i=""
    for
    {
        set i=$ORDER(@table@(i)) QUIT:i=""  
        set evenTotal = evenTotal+@table@(i)
    }
    zwrite evenTotal
}

Hola, acabo de añadir un PDF con las diapositivas que utilicé en el tutorial. Siéntete libre de utilizarlas. Sí te pido que, si lo haces, incluyas un link referenciando a este post en la Comunidad.

Por cierto, para los que me habéis comentado, efectivamente tenía el repositorio de ejemplos en GitHub marcado como privado... ya está accesible: Repositorio GitHub - Ejemplos

Como ya extiendes de %XML.Adaptor, directamente pueden utilizarse las funcionalidades de esa clase para obtener el XML, por ejemplo: 

do objectTest.XMLExportToString(.xml)
write xml

que ya te generará:

<Test><Person><name>John</name><age>22</age></Person><Address><location>New York NY 10036</location></Address></Test>

Parecía que no, pero finalmente llega el momento de cerrar este tutorial de ObjectScript... Publico hoy el Capítulo 6 - ¿Qué pasa con SQL?, dedicado al acceso SQL a IRIS Data Plataform y  cierre de este tutorial. Lo he centrado particularmente en los 2 mecanismos básicos de tratar SQL en ObjectScript, de forma estática, embebiendo SQL en el código ObjectScript, o dinámica, a través de las clases del paquete %SQL.

Por supuesto, hay muuuucho más que contar y aprender... os invito a navegar por esta comunidad, por la sección de formación de InterSystems, por los cursos online gratuitos, por la sección del desarrollador, a visualizar los webinars que periodicamente realizamos y, si tenéis la opción, complementar vuestra formación con un curso oficial. Ah.. y no olvidéis que la documentación es vuestra amiga! Ahí encontraréis explicaciones en detalle y multitud de ejemplos que os ayudarán a avanzar. 

En fin... poco más que decir. Para mí ha sido toda una experiencia.... sobre todo la post-producción 😰😉...  Espero que os haya sido útil... Con haber ayudado a unos pocos, habrá valido la pena. Happy coding!!

Ya están disponibles las nuevas imágenes con la clave extendida en el InterSystems Container Registry. Puedes descargarte las imágenes nuevas ejecutando:

docker pull containers.intersystems.com/intersystems/iris-community:2021.1.0.215.3

docker pull containers.intersystems.com/intersystems/iris-community-arm64:2021.1.0.215.3

docker pull containers.intersystems.com/intersystems/irishealth-community:2021.1.0.215.3

docker pull containers.intersystems.com/intersystems/irishealth-community-arm64:2021.1.0.215.3

Hola Kurro... estos links concretos te funcionan a ti? Creo que los asistentes asociados al New... en el Studio sólo generan el código fuente y lo entregan al editor del Studio... Pero el VSCode no recoge bien esa salida y la muestra tal que así:

<template>
<![CDATA[ BODY##www.intersystems.com:template_delimiter##Include %occInclude /// %Installer Manifest MyApp.MyInstaller Class MyApp.MyInstaller { /// Definición de manifiesto. XData MyManifest [ XMLNamespace = INSTALLER ] { <Manifest> <Namespace> <Configuration> <Database> <!-- Your Manifest code here --> </Database> </Configuration> </Namespace> </Manifest> } /// Este es un generador de métodos cuyo código es generado por XGL. ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ] { #; Permitir que nuestro documento XGL genere código para este método. Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyManifest") } } ##www.intersystems.com:template_delimiter##CLASS##www.intersystems.com:tem... ]]>
</template>

De aquí sí que podríamos extraer el fuente generado... desde el ##Include hasta "MyManifest")}}... pero es un poco engorroso.

En el caso de los Complementos (Add-ins) que automatizan la generación de clases, sí que funcionan prácticamente igual que en el Studio... 

Bueno, ha tardado más de 3 semanas en salir del horno pero aquí lo tienes, calentito, calentito, el Capítulo 5 - Objetos, penúltimo de este tutorial de ObjectScript. En él nos introducimos ya en la parte de Orientación a Objetos. Me ha quedado un pelín largo para mi gusto, algo más de 2 horas, así que tómatelo con tranquilidad, trocealo a tu gusto,...o ¡qué narices!, ¡dale caña y ponle el turbo al video! laugh 

Espero que lo disfrutes y te sirva de ayuda. Ah... recien metido en el horno el Capítulo 6, en el que te contaré un poquito qué pasa con SQL y como también ObjectScript lo incorpora de forma nativa... con él cerraré ya este tutorial. A ver lo que tarda en hacerse. ¡Hasta un rato!