Article
· Mai 15, 2023 5m de lecture

Tuples en tête

Aperçu général

En passant d'IRIS objectScript à Python, on s'aperçoit qu'il existe des différences syntaxiques fascinantes.

L'une d'entre elles concerne la manière dont Python renvoie des tuples à partir d'une méthode à décompression automatique.

En fait, il s'agit d'une méthode qui renvoie plusieurs valeurs. Quelle invention géniale :)

out1, out2 = some_function(in1, in2)

ObjectScript a une autre approche avec les paramètres ByRef et Output.

Do ##class(some_class).SomeMethod(.inAndOut1, in2, .out2)

Où:

  • inAndOut1 représente ByRef
  • out2 représente Output

    Le point initiale (".") devant le nom de la variable passe ByRef et pour Output.

    Le but de cet article est de décrire comment l'utilitaire communautaire PyHelper a été amélioré pour donner une façon pythonique de tirer parti des paramètres ByRef et Output. Il donne accès à %objlasterror et a une approche pour la gestion des types Python None.
     

Exemple ByRef

L'invocation normale pour python intégré serait :

oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('er12345')

Lorsque cette méthode ne parvient pas à s'ouvrir, la variable "oHL7" est une chaîne vide.
Dans la signature de cette méthode, il y a un paramètre d'état qui est disponible pour le script de l'objet qui donne une explication du problème exact.
Par exemple :

  • L'enregistrement peut ne pas exister
  • L'enregistrement ne peut être ouvert dans le mode d'accès simultané exclusif par défaut ("1"), pendant un timeout.
ClassMethod %OpenId(id As %String = "", concurrency As %Integer = -1, ByRef sc As %Status = {$$$OK}) As %ObjectHandle

La méthode TupleOut peut aider à renvoyer la valeur de l'argument sc dans un contexte python.
 

> oHL7,tsc=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['sc'],1,'er145999', 0)
> oHL7
''
> iris.cls("%SYSTEM.Status").DisplayError(tsc)
ERROR #5809: Objet à charger introuvable, classe 'EnsLib.HL7.Message', ID 'er145999'1
```

La liste ['sc'] contient un seul élément dans ce cas. Elle peut retourner plusieurs valeurs ByRef, et dans l'ordre spécifié. Ce qui est utile pour décompresser automatiquement vers les variables python prévues.

La gestion des paramètres de sortie (Output) en cas d'exemple

Code Python :

> oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('145')
> oHL7.GetValueAt('<%MSH:9.1')
''

La chaîne renvoyée est vide, mais est-ce parce que l'élément est effectivement vide OU parce que quelque chose s'est mal passé ?
Dans le script objet, il existe également un paramètre de sortie d'état (pStatus) auquel il est possible d'accéder pour déterminer cette condition.

Code script objet :

> write oHL7.GetValueAt("<%MSH:9.1",,.pStatus)
''
> Do $System.Status.DisplayError(pStatus)
ERROR <Ens>ErrGeneral: Aucun segment n'a été trouvé lors du trajet '<%MSH'

Avec TupleOut, la fonctionnalité équivalente peut être atteinte en renvoyant et en décompressant à la fois la valeur de retour de la méthode ET le paramètre de sortie d'état.

Code Python :

> hl7=iris.cls("EnsLib.HL7.Message")._OpenId(145,0)
> val, status = iris.cls("alwo.PyHelper").TupleOut(hl7,"GetValueAt",['pStatus'],1,"<&$BadMSH:9.1")
> val==''
True
> iris.cls("%SYSTEM.Status").IsError(status)
1
> iris.cls("%SYSTEM.Status").DisplayError(status)
ERROR <Ens>ErrGeneral: Aucun segment n'a été trouvé lors du trajet '<&$BadMSH'1

Variable spéciale %objlasterror

Dans ObjectScript, il est possible d'accéder à des variables de pourcentage dans le cadre d'une méthode.
Dans certains cas, il est utile de détecter la variable spéciale %objlasterror ou d'y accéder après avoir appelé une API CORE ou une API de tiers.
La méthode TupleOut permet d'accéder à %objlasterror, comme si elle avait été définie en tant que paramètre de sortie, lors de l'invocation de méthodes à partir de Python.

> del _objlasterror

> out,_objlasterror=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['%objlasterror'],1,'er145999', 0)

> iris.cls("%SYSTEM.Status").DisplayError(_objlasterror)
ERROR #5809: Objet à charger introuvable, classe 'EnsLib.HL7.Message', ID 'er145999'1

Quand "None" n'est pas une chaîne

TupleOut traite les références python "None" comme objectscript "undefined". Cela permet aux paramètres d'être définis par défaut et aux méthodes de se comporter de manière cohérente.
C'est important, par exemple, dans le cas de %Persistent::%OnNew, où la méthode %OnNew n'est pas déclenchée lorsque "None" est fourni comme valeur initiale "initvalue", alors qu'elle serait déclenchée si une chaîne vide était fournie.

En objectscript, l'implémentation pourrait être la suivante :

do oHL7.myMethod("val1",,,"val2")

Notez l'absence de variables entre les virgules.

TupleOut facilite le même comportement avec :

Python:

iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,"val1",None,None,"val2")

Une autre façon d'envisager la question est d'avoir une implémentation du code d'invocation en une seule ligne, qui se comporte de manière flexible en fonction de la configuration préalable des variables :

Object Script:

set arg1="val1"
kill arg2
kill arg3
set arg4="val2"
do oHL7.myMethod(.arg1, .arg2, .arg3, .arg4)

TupleOut facilite le même comportement avec :

Python:

arg1="val1"
arg2=None
arg3=None
arg4="val2"
iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,arg1,arg2,arg3,arg4)

Liste et dictionnaires

Lors de la gestion des paramètres d'entrée, de ByRef et Output, TupleOut utilise la correspondance automatique de PyHelper entre: l
les listes IRIS et les listes Python
les tableaux IRIS et les tableaux Python
Il prend soin de toujours utiliser des chaînes pour représenter les clés du dictionnaire lorsqu'il passe des tableaux IRIS aux types Dict de Python.

Conclusion

J'espère que cet article contribuera à inspirer de nouvelles idées et discussions sur les idées et suggestions relatives à Python intégré.

J'espère aussi qu'il encouragera à explorer la flexibilité d'IRIS, qui peut facilement s'adapter à de nouveaux défis.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer