Are immutable properties supported in ObjectScript classes?
Can we make any property immutable once it value is set? For example, I may have a property called RecordCreatedTime to track when the record is created in IRIS, and once it is set, I don't want anyone to modify the value.
Comments
Class My.Class
{
Property MyProperty As %String [ReadOnly];
Method %OnNew(init As %String) As %Status [ Private, ServerOnly = 1 ]
{
set i%MyProperty = init
}
} And use it as
set obj = ##class(My.Class).%New("Some initial value")
write obj.MyProperty --> Some initial value
set obj.MyProperty --> <CANNOT SET THIS PROPERTY>Thanks for the response. I can see this is helpful in some of use cases!
1. If it's a one-off thing redefine your property setter:
Class Test.RO Extends %Persistent
{
Property RecordCreatedTime As %TimeStamp [ InitialExpression = {$ZDATETIME($ZTIMESTAMP, 3, 1, 3)} ];
Method RecordCreatedTimeSet(value As %TimeStamp) As %Status
{
if i%RecordCreatedTime="" {
set i%RecordCreatedTime=value
}
quit $$$OK
}
/// do ##class(Test.RO).test()
ClassMethod test()
{
set obj = ..%New()
write obj.RecordCreatedTime,!
set obj.RecordCreatedTime = "2000-01-01 00:00:01"
write obj.RecordCreatedTime,!
}
}It's also automatically set during object creation courtesy of InitialExpression, you can remove it if you want to set the value yourself.
2. If you have the same immutable property or a set of immutable properties you can write an abstract class:
Class Test.Base [Abstract]
{
Property RecordCreatedTime As %TimeStamp [ InitialExpression = {$ZDATETIME($ZTIMESTAMP, 3, 1, 3)} ];
Method RecordCreatedTimeSet(value As %TimeStamp) As %Status
{
if i%RecordCreatedTime="" {
set i%RecordCreatedTime=value
}
quit $$$OK
}
}And add it to inheritance whenever you need:
Class Test.RO Extends (%Persistent, Test.Base)
{
}3. Finally if you have a lot of immutable properties and they are all different you'll need a custom datatype. Custom datatype defines method generators for getters, setters and all other property methods. Let's inherit from %String so we only need to redefine a setter:
Class Test.ROString Extends %String
{
/// Generate Setter
Method Set(%val) [ CodeMode = objectgenerator, NoContext ]
{
quit:%mode'="propertymethod" $$$OK
do %code.WriteLine($c(9) _ "if i%" _ $g(%member) _ "="""" {")
do %code.WriteLine($c(9,9) _ "set i%" _ $g(%member) _ "=%val")
do %code.WriteLine($c(9) _ "}")
do %code.WriteLine($c(9) _ "quit $$$OK")
quit $$$OK
}
}Now we create a property of Test.ROString type:
Class Test.RO Extends %Persistent
{
Property RecordCreatedTime As Test.ROString [ InitialExpression = {$ZDATETIME($ZTIMESTAMP, 3, 1, 3)} ];
}And it would be immutable. In fact if we check a generated setter:
zRecordCreatedTimeSet(%val) public {
if i%RecordCreatedTime="" {
set i%RecordCreatedTime=%val
}
quit 1 }It would look quite similar to what I have wrote in (1), only automatically generated.
Thank you very much for the detailed responses! This is very helpful.