Written by

Question omer · Feb 13, 2024

Create a datatype that overrides the Set and Get

I want to create a datatype that Extends from String and in its set and get it will parse the string or do whatever - my GET works, my SET doesn't.

A deeper explanation of what i am trying to do: Basically none of the usual LogicalToStorage and other functions listed in Datatype creation in the manual is helpful to me, So i wanted to write the Get and Set functions in the Datatype so when compiled each property in other class that is of that type would get its PropertySet() and PropertyGet() overridden, That way i can implement any behaviour of that datatype as i please - "behind the scenes".

an example of what i tried:
Class ParserString Extends %String   [ ClassType = datatype, ProcedureBlock ]

{

Method Get(){ Q ##class(parser).parse(%val)} // this works

Method Set(){ S %val = "asd" Q 1} // this did not work, I also tried to create a generator but was not able to make it work

}
 

Product version: Caché 2013.1

Comments

Enrico Parisi · Feb 13, 2024

I don't think you can implement/override getter and setter in datatype definition.

Depending on your actual needs, you can implement LogicalToStorage  and StorageToLogical.

Please note that implementing getter and setter (PropertyGet() and PropertySet()) has no effect in SQL projection.

0
omer  Feb 13, 2024 to Enrico Parisi

Indirectly i can override the getter. The flow is this:
1. In the datatype i write a Get() method

2. in the class i have a Property prop As %MyDataType
3. i compile and the function Get from the data type gets compiled as propGet() inside my class
As you can see this is a very indirect way to override a Get method of any property with that datatype. (and it works, But i am having problems doing the same for the Set)
And my intention is to create a datatype that is also relevant to RegisteredObjects, That is why LogicalToStorage for example doesn't really suit me. 
If i have a RegisteredObject class then i won't save to storage anyway..
And while i understand i am using the Datatype not as intended this is the only way to make what i need.

0
David Hockenbroch  Feb 13, 2024 to omer

I've never done it this way, just by overriding those methods in the class definition containing the property, but I do know in that case Set has to take a value as an argument. Maybe it's not recognizing your Set method because it doesn't match the signature of the usual Set method. When you override it in a class, it looks like this:

Method NewProperty1Set(Arg As %String) As %Status [ ServerOnly = 1 ]

In that case, Arg is the value that the process is trying to set the value of the property to. So it might have to be something like:

Method Set(Arg as %String){ S %val = "asd" Q 1}

Or if you wanted to some something with the input value, you could use Arg to do that?

0
omer  Feb 18, 2024 to David Hockenbroch

I have tried that, Still did not work.
 

0
Enrico Parisi  Feb 18, 2024 to David Hockenbroch

Within setter and getter method you need to use Instance Variable to set/get the actual property value:

Property NewProperty1 As%String;
Method NewProperty1Get() As%String [ ServerOnly = 1 ]
{
    Quit i%NewProperty1
}

Method NewProperty1Set(Arg As%String) As%Status [ ServerOnly = 1 ]
{
    Set i%NewProperty1=123Quit$$$OK
}

To implement it in datatype class try using a method generator.

Maybe if you explain what you are trying to achieve there can be a different solution.

0
Enrico Parisi · Feb 18, 2024

Thinking of this, in fact I really believe it's not possible to implement setter/getter methods in datatype classes because datatype methods are, by design, classmethods and getter/setter methods are and must be instance methods.

0
omer  Feb 20, 2024 to Enrico Parisi

Indeed i have gotten to the same conclusion, I have decided to bubble up this problem and solve it with a different approach. Thx!

0