davi massaru te... · Dec 13, 2022

objectscript changes in Caché IRIS migration to IRIS

HI ! I'm working on a caché upgrade to IRIS.

in some abstration cls classes, to get a property was used $METHOD(..Obj, propertyName_"Get").
On Caché 2018,  had as a return property value, if the property does not exists, an exception of type <PROPERTY DOES NOT EXIST> throwed

Now, on IRIS 2022.1,  will always be throwed an exception of type "<METHOD DOES NOT EXIST>".

I can change  $METHOD  to  $PROPERTY, but as it is an abstract class, I cannot guarantee the type of the referenced Object, if the property is encapsulated or private, I need call $METHOD(..Obj, propertyName_"Get").

What would be the ideal way to solve this problem? 

Have people in the community already gone through similar behavior changes when evolving the database to IRIS?

(Cahé X IRIS)

Product version: IRIS 2022.1
$ZV: IRIS for UNIX (Ubuntu Server 18.04 LTS for x86-64) 2022.1 (Build 209U) Tue May 31 2022 12:20:34 EDT
0 263
Discussion (8)2
Log in or sign up to continue

Are you sure,  ..ObjOrigem contains a VALID object reference? Your output shows just a string "%Library.DynamicObject". A valid OREF looks like "nn@%Library.DynamicObject". What is the output of $isobject(..ObjOrigem)?

Anyway, the $method(oref, "Propname"_"Get") works in IRIS, at least, in my IRIS 2021.2

USER>set obj={"Id":"myId"}
USER>write $property(obj,"Id")  --> myId
USER>write $method(obj,"IdGet") --> myId
USER>write $zv  -->  IRIS for UNIX (Ubuntu Server LTS for x86-64) 2021.2 (Build 649U) Thu Jan 20 2022 08:49:51 EST
USER>write obj  -->  5@%Library.DynamicObject

output of $isobject(..ObjOrigem) is "1"

I tried to do the same test.


LISDEV>set obj={"Id":"myId"}

LISDEV>write $property(obj,"Id")  
LISDEV>write $method(obj,"IdGet")

WRITE $METHOD(obj,"IdGet")
<METHOD DOES NOT EXIST> *IdGet,%Library.DynamicObject
LISDEV>write $zv
IRIS for UNIX (Ubuntu Server 18.04 LTS for x86-64) 2022.1 (Build 209U) Tue May 31 2022 12:20:34 EDT
LISDEV>write obj


@Julius Kavay, according to $zv , you are running IRIS 2021.1, I'm running IRIS 2022.1

It seems, we have to wait for someone with the same version installed as you, or you ask WRC.

By the way, does the release notes for 2022.1 mentioned  changes in dynamic classes?

Issue looks specific to dynamic objects:

USER>w $zv
IRIS for Windows (x86-64) 2022.1 (Build 209U) Tue May 31 2022 12:16:40 EDT
USER>set obj={"Id":"myId"} 
USER>write $property(obj,"Id")
USER>write $method(obj,"IdGet")
WRITE $METHOD(obj,"IdGet")
<METHOD DOES NOT EXIST> *IdGet,%Library.DynamicObject

USER>set obj = ##class(User.A).%New()
USER>write $property(obj,"Id")
USER>write $method(obj,"IdGet")

It seems, there is a problem or (at least) a change: the above works (tested right now) in Cache-2018.1.1, IRIS 2019.1 and IRIS-2021.2

If it doesn't work in 2022.1 then the question is, why?

the problem is not IRIS but the understanding of different objects

Your example uncovers that you are mixing up 2 different things

There are Objects that extend %RegisteredObject  (or some derivate of it.
properties in these classes get automatically generated methods.
like the ....Get you  @Eduard Lebedyuk  wrote this related article.

Useful auto-generated methods
you find those properties also in the realted %Dictioary classes.

Your example is a %DynamicObject and something total different.
There is the JSON style object
but it has nothing to do with the classic object architecture
implemented in Caché and IRIS.

Mixing of methods between those 2 implementations is just not foreseen.
%DynamicObjeckts have an Iterartor. Unknown to %RegisteredObject.
and many more

A future release of IRIS will restore the ability of %DynamicArray and %DynamicObject classes to dispatch method calls on the method names of the form "propertyGet" and "propertySet".  However,  $PROPERTY(dynobj,"Id") should be more efficient than $METHOD(dynobj,"IdGet") so we recommend using $PROPERTY over using $METHOD when working with %DynamicObject class objects.  When the property name is known before execution time then dynobj.Id is the best way to do a simple property access of a %DynamicObject element with key name "Id".

A change was made to how IRIS dispatched method calls because there existed a few unusual cases where there was no property named "property" but the programmer was trying to dynamically dispatch to a method with the name "propertyGet" and the result was an undefined property error rather than a method call.  The change was made so that a method named "propertyGet" could always be correctly called when there was no property named "property".

Every possible string is a legal %DynamicObject key name and if the key name element is not otherwise defined then that key name element contains the empty string value.  The implementation of the %DynamicObject class does not include a list of all legal property names since all key name strings are legal.  The new way of dynamically dispatching method calls with names like "propertyGet" would first check if the property named "property" existed before attempting a property dispatch instead of method dispatch.  Since a %DynamicObject class object did not contain the name "property" in the list of legal property names and did not contain a method called "propertyGet" in the list of legal method names, the result of evaluating $METHOD(dynobj,"propertyGet") was a <METHOD DOES NOT EXIST> signal.  The future release of IRIS will have $METHOD(dynobj,"propertyGet") dispatch a property access rather than attempting a dynamic dispatch of a method access.

I should point out that "%" is a legal key name string but $METHOD(dynobj,"%Get) did not fetch (and will not fetch) the element with key name "%" because a %DynamicObject does contain a method named "%Get".  A call on a defined method name always occurs before attempting a dynamic method dispatch.

See the documentation on the

methods which can be used with subclasses of the %RegisteredObject class.