Question
· 5 hr ago

How can I add an ancestor to a class programmatically?

Hi Developers!

Consider I have a persistent class derived from %Persistent and I want it to be derived from %JSON.Adaptor to enjoy all the JSON features.

Can I do it programmatically? 

So, it'd be wonderful to have a method in some util class that makes it happen? Something like:

Do ClassUtil.AddAncestor("MyPackage.MyPersistentClass","%JSON.Adaptor")

Any ideas?

Discussion (3)4
Log in or sign up to continue

You can programmatically add an ancestor to a class by utilizing the %Dictionary.ClassDefinition API in ObjectScript. Here's how you can accomplish it:

  1. Use the %Dictionary.ClassDefinition class to represent and modify the class definition.
  2. Modify the Super property of the class definition to include the new ancestor (e.g., %JSON.Adaptor).
  3. Save the modified class definition and recompile the class.

Below is an example method to add an ancestor:

ClassMethod AddAncestor(className As %String, ancestor As %String) As %Status
{
    // Open the existing class definition
    set clsObj = ##class(%Dictionary.ClassDefinition).%OpenId(className)
    if clsObj = "" {
        write "Class not found!", !
        quit $$$ERROR($$$GeneralError, "Class not found")
    }

    // Add the new ancestor to the Super property
    set currentAncestors = clsObj.Super
    if currentAncestors '= "" {
        set newAncestors = currentAncestors _ "," _ ancestor
    } else {
        set newAncestors = ancestor
    }
    set clsObj.Super = newAncestors

    // Save and compile the updated class
    set status = clsObj.%Save()
    if $$$ISERR(status) {
        do $SYSTEM.OBJ.DisplayError(status)
        quit status
    }
    set status = $SYSTEM.OBJ.Compile(className, "k")
    if $$$ISERR(status) {
        do $SYSTEM.OBJ.DisplayError(status)
        quit status
    }

    write "Ancestor added successfully!", !
    quit $$$OK
}

You can invoke the method like this:

do ##class(YourNamespace.YourClass).AddAncestor("MyPackage.MyPersistentClass", "%JSON.Adaptor")

This approach first loads the existing class definition, then updates the Super property to include the additional ancestor, and finally saves and compiles the changes [1].

Sources: