Nova postagem

検索

Artigo
· Abr. 22 7min de leitura

Set, Get, and Don't Fret with JSON

The Good Old Days

The %Library.DynamicObject class has been in IRIS since before it became IRIS. If you have been using it since the Cache days, you may want to brush up on some of its changes.

In Cache 2018, the %Get method only had one argument. It was the key to retrieving from the JSON, meaning that if your JSON object called myObj, it would look like the following:

{
    “mybool”:true,
    “mynum”:1234,
    “mystring”:”Hello World!”
}

Exploiting myObj.%Get(“mybool”) would return a 1, myObj.%Get(“mynum”) would return 1234, and myObj.%Get(“mystring”) would return the string “Hello World!” 

Setting those parameters, on the other hand, required a bit more work. For instance, appointing a JSON property to a 0 could mean the number 0, a boolean value meaning false, or a literal string “0”. This is why the %Set method always had the third, optional argument. To create the above-mentioned JSON object, we could utilize the following code:

set myObj = ##class(%Library.DynamicObject).%New()
do myObj.%Set(“mybool”,1,”boolean”)
do myObj.%Set(“mynum”,1234,”number”)
do myObj.%Set(“mystring”,”Hello World!”,”string”)

Yet, in this case, we could also leave the third argument out of the last two. Then, 1234 would be recognized as numeric since it is not quoted, whereas “Hello World!” would be identified as a string because it is quoted. If we wanted to add the value 1234 to the object as a string, we could change the string to numeric. We could also specify the “null” type. In that case, the value must be “”. In practice, however, we often add those values from variables in our ObjectScript code. Due to that, it may be better to specify this argument, just in case the variable might be a string or numeric, to ensure that our JSON arrives at its destination encoded correctly.

How I Learned to Stop Worrying About <MAXSTRING> and Love JSON

As the wise Billy Joel once said, “The good old days weren’t always good, and tomorrow ain’t as bad as it seems.” The type list for %Set has grown, and the %Get method has acquired a couple of new arguments. What is crucial, they both support “stream” as a type. If you have ever handled receiving a lot of JSON data, you have probably seen a <MAXSTRING> error at some point, when the data contained in the JSON was longer than a typical string in IRIS is allowed to be. The new %Get lets you specify two more arguments, a default value, and a type. Your older code has not stopped working though because those two arguments are optional, and, if omitted, the methods will work precisely as they did in 2018. The default value is returned if nothing is found for the given key. The type functions similarly to the type argument in the %Set method. You can also specify what data type you are retrieving. Consider the following try/catch block:

try{
    Set mydata = myObj.%Get(“mydata”,”N/A”)
}
catch ex{
    if ex.Name = “<MAXSTRING>”{
        set mydata = myObj.%Get(“mydata”,,”stream”)
    }
}

It will attempt to set mydata to the value located inside “mydata” in the JSON object. If that item does not exist, it will return “N/A” instead. If that item is too long for a string, the system will throw an exception to the catch block. We should check the name of that exception since if a different exception occurred, it would not make sense to try to get the data as a stream either. You can read more on exception handling here. If it is <MAXSTRING>, we will specify that we want to retrieve mydata as a stream instead. Retrieving the data as a stream will return an object of the class %Stream.DynamicCharacter. It will never trigger a <MAXSTRING> exception, although it may throw a <STORE> exception if the process’s memory limit is exceeded.

If you take the approach described above, you will not know whether mydata in the code is a string or a stream. It means that you will have to follow up with the code similar to the one below:

if $ISOBJECT(mydata){
    //Place handling for streams here
}
else{
    //Place handling for strings here
}

You could also employ the stream option every single time guaranteeing that you always have a stream to work with. However, it would create unnecessary resource usage and overhead in your code.

Another option is to add a stream to a dynamic object using %Set. Check out the following example:

set mystream = ##class(%Stream.FileBinary).%New()
do mystream.LinkToFile(“/path/to/your/file”)
do myObj.%Set(“mydata”,mystream,”stream”)

The data in your file will now go into the mydata field of your dynamic object.

%Set and %Get also encode and decode strings with the help of the Base64 encoding. 

Always keep in mind that Base64 encoding is encoding not encryption! There are no secret keys or passphrases to decode your message, and it is easily reversible. Therefore, you should still use an encrypted protocol, e.g., TLS or HTTPS, for transmission! Base64 is operated to transmit non-ASCII characters in a way that allows ASCII-only systems to receive them and pass them along.

With that crucial side note out of the way, we can finally look at how this works. If we make one small change to the previous code sample, the contents of the file stream will become Base64 encoded.

set mystream = ##class(%Stream.FileBinary).%New()
do mystream.LinkToFile(“/path/to/your/file”)
do myObj.%Set(“mydata”,mystream,”stream>base64”)

On the other hand, if the data in the file was already Base64 encoded and we wanted to convert it to the decoded data, we only need to change one character.

set mystream = ##class(%Stream.FileBinary).%New()
do mystream.LinkToFile(“/path/to/your/file”)
do myObj.%Set(“mydata”,mystream,”stream<base64”)

The greater than or less than signs always point in the direction where conversion takes place. If we convert from an unencoded stream to a Base64 string, the sign will point to the Base64. If we convert a Base64 encoded stream to an unencoded stream, the sign will point from the Base64 to the stream. The same functionality exists for strings when using string>base64 and string<base64 as the type argument. We can utilize these type arguments for the %Get function as well. Note that when we do it, the default value we provided earlier will not be converted. It will be returned literally. Consider the following:

set something = myObj.%Get(“something”,”NA”,”string>base64”)

If the “something” item exists, it will be returned in its Base64 encoded form. However, if it does not exist, “NA” will be returned without being encoded.

There is one caveat to the Base64 encoding option. Only characters with a code between zero and 255 can be encoded in Base64. Character codes greater than 255 will result in a <WIDE CHAR> exception. For example, the following line will cause that exception:

set mychar = $C(256)
do myobj.%Set(“mychar”,mychar,”string>base64”)

So, I Heard You Like JSON . . .

Sometimes, there is JSON in your JSON. The default way of handling this is usually the one you would choose. Yet, another option has been added to the type argument to deal with a different use case. It is the “json” type. Look at the following JSON object:

{
    “mystring”:”Hello World!”,
    “mynumber”:1234,
    “myjson”:{
        “subitem1”:”Hello Mars!”,
        “subitem2”:”Hello Stars!”
    }
}

As a rule, when you run into this, you will operate the %Get method with the key “myjson” to get a dynamic object. Look at the example below:

set myjson = myobj.%Get(“myjson”)
write myjson.%Get(“subitem1”)

The line above would write “Hello Mars!” This is the most common use case in this situation. Yet, there may be situations when you would prefer to get the actual JSON contained within that item as a string. In that case, we can do the following:

set myjson = myobj.%Get(“myjson”,,”json”)
write myjson

It will write out the JSON string exactly the way it is:

{“subitem1”:”Hello Mars!”,”subitem2”:”Hello Stars!”}

It can come in handy in cases where we want to pass along the JSON as it is to another process. Note that, unlike all the other new types, this one is supported only for the %Get method, not the %Set method.

Hip, Hip, Array!

We have been discussing these new objects in the context of the %Library.DynamicObject class so far, but they are also supported for the %Library.DynamicArray class. In that class, %Set and %Get support the same type arguments as in the %Library.DynamicObject class. The dynamic array class has an additional %Push method though. It supports the same types as %Set, excluding the JSON type.

Without further ado, it is probably the right time to review your older codes and implement these changes to your benefit!

1 Comment
Discussão (1)1
Entre ou crie uma conta para continuar
InterSystems Oficial
· Abr. 22

Maintenance Releases 2024.1.4 and 2023.1.6 of InterSystems IRIS, IRIS for Health, & HealthShare HealthConnect are now available

The 2024.1.4 and 2023.1.6 maintenance releases of InterSystems IRIS® data platform, InterSystems IRIS® for HealthTM, and HealthShare® Health Connect are now Generally Available (GA). These releases include the fixes for the following alert recently issued - Alert: SQL Queries Returning Wrong Results | InterSystems. Please share your feedback through the Developer Community so we can build a better product together.

Documentation

You can find the detailed change lists & upgrade checklists on these pages:

Early Access Programs (EAPs)

There are many EAPs available now. Check out this page and register to those you are interested.

How to get the software?

Full installation packages for both InterSystems IRIS and InterSystems IRIS for Health are available from this WRC's InterSystems IRIS Data Platform Full Kits. page. HealthShare Health Connect kits are available from WRC's HealthShare Full Kits page. Container images are available from the InterSystems Container Registry.

Availability and Package Information

This release comes with classic installation packages for all supported platforms, as well as container images in Docker container format.  For a complete list, refer to the Supported Platforms document. The build number for these Maintenance Releases are: 2024.1.4.512.0 and 2023.1.6.809.0.

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· Abr. 22

Confusing container tags on containers.intersystems.com

I've conducted some tests using different InterSystems IRIS Community Edition container images, which I pulled from https://containers.intersystems.com.

During this process, I noticed some inconsistencies that I’d like to clarify:

  • The tag latest-preview pulls: InterSystems IRIS Version 2025.1.0.204
  • The tag latest-cd pulls: InterSystems IRIS Version 2024.3.0.217
  • The tag 2025.1 pulls: InterSystems IRIS Version 2025.1.0.223

This behavior was a bit confusing to me, especially since latest-preview does not point to the most recent 2025.1 build.

Could someone please confirm if this is the intended setup or provide guidance on how these tags are meant to be used?

Andreas

2 Comments
Discussão (2)2
Entre ou crie uma conta para continuar
Artigo
· Abr. 22 4min de leitura

My options to learning more from READY 2025

This year I will go to the READY 2025 event (https://community.intersystems.com/post/registration-open-intersystems-ready-2025). See my plans:

60% of my topics are covered by developer sessions and the other 40% I will reach using 1:1 meetings, tech exchange and focus groups. I know, it is not possible stay at all sessions, but I will to try 30-40% of sessions. See it:

Topics of my Interest Session or 1:1 Meetings, Tech Exchange and Focus Groups
IKO, ICR GO IKO At Your Enterprise: GOtchas, GOvernance, & GOing-Live
VSCode and Dev Tools 1:1 Meetings, Tech Exchange and Focus Groups
InterSystems Reports Use Case: From Zero to Hero With InterSystems Reports
FHIR SQL Builder Developing on FHIR in 2025
API Manager InterSystems IRIS for Health & IAM FHIR Interoperability
Data migration from other DB products 1:1 Meetings, Tech Exchange and Focus Groups
Upgrade from Cache/Ensemble/DeepSee to IRIS 1:1 Meetings, Tech Exchange and Focus Groups
Observability and Monitoring (Open Telemetry) What's going on? Monitoring and Observability of IRIS
HL7: Modeling, development and Productive tools 1:1 Meetings, Tech Exchange and Focus Groups
FHIR: Modeling, development and Productive tools Developing on FHIR in 2025, Practical Approaches to Transforming Your Data into FHIR, Taking the Fear out of   FHIR: Fast-tracking Organizational FHIR readiness
High Availability and Scalability Operations & Scalability with InterSystems IRIS: From Zero to Hero
Resilience Resilience by Design: Business Continuity Through Secure Backup
Security Security in the Cloud, Security Roadmap, Encryption in Transit and InterSystems IRIS
QA and tests 1:1 Meetings, Tech Exchange and Focus Groups
Python Productive Data Science with IRIS and Python, Succeeding with Python Development on IRIS (Interoperability, Virtual Environments, Debugging, Client Library Experience, etc.)
Java, DotNet and PEX and native SDKs 1:1 Meetings, Tech Exchange and Focus Groups
Advanced SQL and tune strategies 1:1 Meetings, Tech Exchange and Focus Groups
WSGI 1:1 Meetings, Tech Exchange and Focus Groups
Vector Search How Vector Search and RAG make your apps Intelligent, without feeling Artificial, First customers using Vector Search: Real-World Experiences and Lessons Learned
Document Database 1:1 Meetings, Tech Exchange and Focus Groups
Columnar Database 1:1 Meetings, Tech Exchange and Focus Groups
OLAP and BI/Analytics New experience with InterSystems IRIS Business Intelligence, Population Health Analytics: Health Insight + Power BI, Analytics & AI with InterSystems IRIS: From Zero to Hero
GenAI Analytics & AI with InterSystems IRIS: From Zero to Hero, LLM Use Cases with HealthShare, How Vector Search and RAG make your apps Intelligent, without feeling Artificial, Understanding AI-Ready Data, Using SerenityGPT to Build Out an Application GenAI Middleware at InterSystems, Patterns for Seamlessly Integrating AI Agents into InterSystems IRIS
IntegratedML and new time series prediction 1:1 Meetings, Tech Exchange and Focus Groups
Web Gateway with NGINX 1:1 Meetings, Tech Exchange and Focus Groups
REST API/Microservices development 1:1 Meetings, Tech Exchange and Focus Groups
Interoperability InterSystems IRIS for Health & IAM FHIR Interoperability, Transforming Transformations, Unlocking Interoperability with InterSystems Health Connect
IoT, MQTT and Interoperability with devices 1:1 Meetings, Tech Exchange and Focus Groups
Adaptive Analytics 1:1 Meetings, Tech Exchange and Focus Groups
Interoperability with Cloud resources 1:1 Meetings, Tech Exchange and Focus Groups
Messaging and Streaming data 1:1 Meetings, Tech Exchange and Focus Groups
IPM Deploying Solutions using InterSystems Package Manager (IPM) and OCI Artifacts
DevOps Advanced InterSystems IRIS Automation using Ansible
IRIS Roadmap Data Platforms Vision and Roadmap
Developer/Community/Learning resources Partnering for Success: Collaborative Innovations With InterSystems & You
Healthshare HealthShare AI Assistant: Unlocking the Power of Every Patient Record, HealthShare Change Control (HS-CTRL), HealthShare End User Apps: New & Next, HealthShare Unified Care Record: New & Next, HealthShare Vision & Roadmap: Fueling Faster AI Adoption Through Trusted Health Data, LLM Use Cases with HealthShare, Onboarding Clinical Data Feeds: InterSystems deploys accelerators to Streamline Connections and Increasing Accuracy, Using HIE Data for Public Health, Optimizing Query Performance in Health Insight, Population Health Analytics: Health Insight + Power BI, Provider Directory: New & Next, Transitioning HealthShare from On-Prem to HealthShare Cloud
InterSystems SaaS solutions Meet InterSystems EMPI, InterSystems Health Gateway, InterSystems OMOP Solution, IRIS, & IRIS for Health, as a Managed Service
2 Comments
Discussão (2)2
Entre ou crie uma conta para continuar
Artigo
· Abr. 22 6min de leitura

Reflexões sobre Programação com IA Generativa

Há treze anos, obtive dois diplomas de graduação em engenharia elétrica e matemática, e logo em seguida comecei a trabalhar em tempo integral na InterSystems, sem usar nenhuma das duas. Uma das minhas experiências acadêmicas mais memoráveis e perturbadoras foi em Estatística II. Em uma prova, eu estava resolvendo um problema de intervalo de confiança moderadamente difícil. O tempo estava acabando, então (sendo um engenheiro) escrevi a integral definida na folha de prova, digitei-a na minha calculadora gráfica, escrevi uma seta com "calculadora" sobre ela e depois escrevi o resultado. Meu professor, carinhosamente conhecido como "Dean, Dean, a Máquina de Reprovar", me chamou ao seu escritório alguns dias depois. Ele não gostou nada do meu uso da calculadora gráfica. Achei isso irracional – afinal, era Estatística II, não Cálculo II, e eu fiz a parte de Estatística II corretamente... certo? Acontece que escrever "calculadora" sobre aquela seta me rendeu zero crédito na questão e uma risada do Dean; se eu tivesse omitido, teria tirado zero na prova. Eita.

Tenho repensado bastante nesse evento recentemente. A IA Generativa faz com que minha TI-89 Titanium, coberta de adesivos de estrelas por notas máximas nas aulas de matemática do ensino médio e modificada para rodar Tetris, pareça um tijolo de plástico superfaturado. Bem, era um tijolo de plástico superfaturado há 20 anos, mas ainda é hoje também.

  

My trusty old TI-89 Titanium

Riscos e Regras

Com o advento de ambientes de desenvolvimento integrado (IDEs) realmente bons e habilitados por IA, existe o potencial para que a IA faça o trabalho do desenvolvedor de software de nível inicial médio... certo? Se esse desenvolvedor de software de nível inicial estiver usando Python – ou alguma outra linguagem suficientemente popular na qual os modelos foram treinados – então sim. E se você se sentir confortável com o débito técnico de montanhas de código que podem ser lixo completo – ou pior ainda, majoritariamente bom com pequenos trechos de lixo escondidos – então sim. E se você tiver algum meio místico para equipar desenvolvedores de software de nível inicial em funções de principal/arquiteto sem exigir que eles escrevam nenhum código, então sim. Isso é muitas ressalvas, e precisamos de algumas regras para mitigar esses riscos.

Nota: estes riscos são independentes das preocupações com direitos autorais/propriedade intelectual que são de mão dupla: estamos infringindo código protegido por direitos autorais no conjunto de dados de treinamento ao usar a saída da GenAI? Estamos arriscando nossa própria propriedade intelectual ao enviá-la para a nuvem? Para este artigo, assumimos que ambos estão cobertos por nossa escolha de modelo/provedor de serviços, mas estas são grandes preocupações impulsionadoras no nível corporativo.

Regra nº 1: Escopo do Trabalho

Não use GenAI para fazer algo que você mesmo não conseguiria, além ou perto dos limites da sua compreensão e capacidade atuais. Voltando à ilustração original, se você está em Estatística II, pode usar GenAI para fazer Cálculo II – mas provavelmente não Estatística II, nem Estatística I e definitivamente não Teoria da Medida. Isso significa que, se você é um estagiário ou desenvolvedor de nível inicial, não deve deixar que ela faça nenhum do seu trabalho. Usar GenAI como uma busca no Google turbinada é totalmente aceitável, e usar um autocomplete inteligente pode ser OK, apenas não deixe que ela escreva código novo e do zero para você. Se você é um desenvolvedor sênior, use-a para fazer trabalho de desenvolvedor de nível inicial em tecnologias nas quais você tem proficiência de nível sênior; pense nisso como uma delegação semelhante e revise o código como se tivesse sido escrito por um desenvolvedor de nível inicial. Minha experiência de desenvolvimento de software assistido por IA tem sido com o Windsurf, que eu gosto nesse aspecto: consegui treiná-lo um pouco, dando-lhe regras e conselhos para lembrar, seguir e (como um desenvolvedor de nível inicial) ocasionalmente aplicar no contexto errado.

Regra nº 2: Atribuição

Se a GenAI escrever uma grande parte do código para você, certifique-se de que a mensagem de commit, o próprio código e qualquer documentação legível por humanos associada sejam muito claros sobre isso. Deixe óbvio: eu não escrevi isso, um computador escreveu. Isso é um serviço para aqueles que revisam seu código: eles devem tratá-lo como escrito por um desenvolvedor de nível inicial, não por você, e como parte da revisão devem questionar se a IA está fazendo coisas além da sua profundidade técnica (o que pode estar errado – e você não saberia). É um serviço para aqueles que olham seu código no futuro e tentam determinar se é lixo. E é um serviço para aqueles que tentam treinar futuros modelos de IA em seu código, para evitar o colapso e "defeitos irreversíveis nos modelos resultantes".


Regra nº 3: Modo de Aprendizagem e Reforço

Quando você está na faculdade cursando Estatística II, há algum valor no reforço das habilidades aprendidas em Cálculo II. Para ser honesto, esqueci a maior parte de ambos agora, por falta de uso. Talvez "Dean, Dean, a Máquina de Reprovar" estivesse certo afinal. Em situações em que seu objetivo principal é aprender coisas novas ou reforçar suas habilidades existentes, novas (ou de anos atrás!), fazer todo o trabalho sozinho é a melhor maneira de seguir. A prototipagem rápida é uma exceção (embora as Regras nº 1 e nº 2 ainda se apliquem!), mas mesmo no trabalho diário regular seria prejudicial tornar-se excessivamente dependente da GenAI para realizar tarefas de "desenvolvedor de nível inicial", pessoal ou organizacionalmente. Sempre precisaremos de desenvolvedores de nível inicial, porque sempre precisaremos de desenvolvedores principais e arquitetos, e o caminho entre os dois é uma função contínua. (Aí, eu me lembro de algumas coisas de matemática!)

Isso é algo que eu adoraria ver como um recurso de IDE: alternar para o "modo de aprendizado" onde a IA observa/orienta você em vez de fazer qualquer trabalho por você. Na ausência de alguma implementação personalizada em software, você também pode optar por usar a IA dessa maneira.

Regra nº 4: Reflexão

Não se perca no turbilhão de trabalho, entregas e reuniões. Reserve um tempo para refletir. Isso é importante em geral e importante no uso da GenAI especificamente.

  • Essa tecnologia está tornando minha vida melhor ou pior?
  • Está me tornando mais inteligente ou mais burro?
  • Estou produzindo mais valor ou apenas mais resultado?
  • Essa saída inclui dívida técnica incorrida por conveniência?
  • Estou aprendendo de forma mais eficaz ou esquecendo como aprender?
  • Como as soluções da IA se comparam às que tenho em mente? Ignoro algo que a IA presta atenção? A IA sistematicamente ignora coisas que são importantes para mim?
  • Estou me tornando como o ChatGPT, introduzindo sem alma e aleatoriamente listas com marcadores e texto em negrito nos documentos que escrevo? (Oh não!!)

Um Pensamento Final: GenAI e Desenvolvimento Baseado em InterSystems IRIS

Em um mundo onde os desenvolvedores esperam que a GenAI seja capaz de fazer o trabalho por eles – ou pelo menos torná-lo muito mais fácil – uma de duas coisas pode acontecer:

  • Tecnologias e linguagens dominantes (veja-se: Python) podem se tornar superdominantes, mesmo que não sejam as melhores para a tarefa em questão. Já que a GenAI é tão boa em Python, por que usar outra coisa?
  • Tecnologias e linguagens de nicho (veja: ObjectScript) podem se tornar mais palatáveis para os desenvolvedores. Aprender uma nova linguagem não é tão difícil se a GenAI puder ajudá-lo a começar rapidamente e fazer as coisas direito.

Minha esperança é que, à medida que fornecedores e líderes de desenvolvimento de software perceberem os riscos que descrevi, as ferramentas tendam a apoiar o último resultado – o que é uma oportunidade para a InterSystems. Sim, as pessoas podem simplesmente usar Python Embutido para tudo, mas nosso legado tecnológico e os pontos fortes da plataforma principal também podem se tornar mais palatáveis, e o ObjectScript pode receber o amor que merece.

Discussão (0)1
Entre ou crie uma conta para continuar