Question
· Dec 25, 2017

How can I redefine marco and recompile code for subclass

Let's say I have Macro.Parent class:

Include Parent
Class Macro.Parent
{

ClassMethod Test()
{
    write "Class: " _ $classname() _ $c(10,13) _ "Value: " _ $$$name
}

}

which references Parent.inc macro name:

#define name "Parent"

Now, I want in my subclass Macro.Child to have Test method with the same code, but to redefine value of name macro.

Currently I have Child.inc with macro name:

#define name "Child"

And Macro.Child class:

Class Macro.Child Extends Macro.Parent
{

ClassMethod Test() [ CodeMode = objectgenerator ]
{
    set parent = ##class(%Dictionary.MethodDefinition).IDKEYOpen(%class.Super, %method.Name)
    do %code.WriteLine(" #include Child")
    do %code.CopyFrom(parent.Implementation)
}

}

So the idea is to have a subclassed method generator that injects the new macro value. Here's how that works:

>do ##class(Macro.Parent).Test()
Class: Macro.Parent
Value: Parent
>do ##class(Macro.Child).Test()
Class: Macro.Child
Value: Child

But that approach has several drawbacks, such as:

  • Need to write a method for each method I want to redefine
  • Seems rather crude

Is there any better way to achieve that? I can't modify Macro.Parent class or Parent.inc macro.

Discussion (6)0
Log in or sign up to continue

Macro.Parent.cls:

Include Parent

Class Macro.Parent
{

ClassMethod Test()
{
  write "Class: " $classname() , ! , "Value: " $$$name 
}

}

Macro.Child.cls:

Include Child

Class Macro.Child Extends Macro.Parent
{

ClassMethod Test()
{
  write "Class: " $classname() , ! , "Value: " $$$name 
}

}

Parent.inc:

#ifndef name
  #define name "Parent"
#endif name

Child.inc:

#define name "Child"

Result:

>do ##class(Macro.Parent).Test()
Class: Macro.Parent
Value: Parent
>do ##class(Macro.Child).Test()
Class: Macro.Child
Value: Child

Then this:

Include Child

Class Macro.Child Extends Macro.Parent
{

ClassMethod first()
{
  #include Child
}

ClassMethod Test() [ PlaceAfter = first ]
{
  write "Class: " $classname() , ! , "Value: " $$$name
}

}

or this:

ClassMethod Test()
{
  #include Child
  write "Class: " $classname() , ! , "Value: " $$$name
}