Intersystems caché - programmatically create new class - intersystems-cache

Is it possible to write ObjectScript method, which will create new class in namespace and compile it? I mean programmatically create new class and store it. If so, can I edit this class using ObjectScript later(and recompile)?
Reason: I have class structure defined in string variable and I need to add new class to namespace according this string.

Nothing is impossible. Everything in Caché can be created programmatically. And, Classes is not a execution. There are at least two ways to do it:
simple SQL Query CREATE TABLE, will create a class.
and as you already mentioned ObjectScript Code, which can do this.
All of definition of any classes defined in other classes. Which you can find in package %Dictionary.
The class itself defined in %Dictionary.ClassDefinition. Which have some properties, for defining any parts of classes. So, this is a simple code which create some class, with one property.
set clsDef=##class(%Dictionary.ClassDefinition).%New()
set clsDef.Name="package.classname"
set clsDef.Super="%Persistent"
set propDef=##class(%Dictionary.PropertyDefinition).%New()
set propDef.Name="SomeProperty"
set propDef.Type="%String"
do clsDef.Properties.Insert(propDef)
do clsDef.%Save()
And in latest versions, there is one more way for create/change class. If you have text of class as you can see it in Studio. Then, you can load it in Caché, with class %Compiler.UDL.TextServices

Yes, it is. You likely want to make use of %Dictionary.ClassDefinition and the related %Dictionary.*Definition classes (especially %Dictionary.PropertyDefinition, %Dictionary.MethodDefinition and %Dictionary.IndexDefinition) to create and/or modify your class. Provided your string contains some reasonable representation of the data, you should be able to create the class this way.
The actual class documentation is available at http://docs.intersystems.com/cache20141/csp/documatic/%25CSP.Documatic.cls?CLASSNAME=%25Dictionary.ClassDefinition
You can then compile the class by calling $system.OBJ.Compile("YourPackage.YourClass","ck").
(Note: If your string contains the exported XML definition of the class, you could also write the XML representation to a stream and then call $system.OBJ.LoadStream() to import the XML definition. I would only recommend this if you have an exported class definition to start with.)

Related

Collect all annotated class name in some scala object

We have various class annotated with a scala macro annotation that add a method to that class. At compile time, We want to add a list of these annotated class in some other object . So that we can access that list at run time. Is there any way to achieve this?
I didn't find a straight way to do this but what I did was pretty simple. Whenever my macro finds my annotated class, It writes the name of the class to a file in resources. At runtime, I made that file content available as a list through a new class method.

Eclipse modeling tool, define a class as a type for an attribut

I try to make a model on eclipse modelling tool and I have in the model a class that use an other class as a type for an attribute.
I have made the class definition but I can't find the way to connect them together.
I have also made the definition for a method with a parameter with the same class type, but there I've no trouble. The class I use as a Type is in the combo box.
How should I do?
If I understand your question correctly, you are trying to create an EMF metamodel, and are using a graphical editor, and try to connect EClasses.
Basically, EMF EClasses can have two kinds of features: EAttributes and EReferences. EAttributes can refer to Java types, like integer or string; while EReferences are used to connect EClasses. In other words, you cannot have an EAttribute refer to another type you added to the diagram; instead you have to create a reference between them.

How can I load a matlab object of which the class definition file was placed in separate package

Is it possible in matlab to load an object of which the class definition file was placed in separate package?
For example:
T = myTestClass;
save('T');
Now I want to place my class in a package, so I create the directory structure as follows:
+myTestPack/#myTestClass/myTestClass.m
Next I try to recover the saved object:
import myTestPack.*
load('T.mat');
The outcome is always:
Warning: Variable 'T' originally saved as a myTestClass cannot be instantiated as an object and will be read in as a uint32.
Is there any way to solve this problem? I would like to restructure my code but a lot of old data was saved as objects.
Maybe I need to add loadobj/saveobj methods to the definition file or maybe there is a way to rename the class from myTestClass to myTestPack.myTestClass?
Thank you for your suggestions!
You need to add loadobj method to your new class. You also need a simple class myTestClass in the old location with just a loadobj method which calls loadobj method of the moved class. MATLAB does not know that you have moved the class. When loading all it knows is that it is of class type myTestClass and tries to create one by looking up myTestClass.

Using a class function to find a file, and include it so the class in that file can be used

So far this one seems to go against the grain of Php OOP. Let me explain further with an example.
class main has a function called get($name), what I would like get to do is based on the value of $name, (e.g. 'path/file') would find the corresponding file and include it, so the class in path/file can be used.
My goal with this and the reason I want to do this, is when I call $main->get('path/file'), I'd like an object returned of the class within the file, so far the only solution I can figure out is to use
include($main->get('path/file'));
And within said file would be an object defined outside the class body within path/file.php, but that doesn't really solve the issue as it limits me to using the object defined in that file, and I can only use this include call outside a class body. Does anyone have any ideas on how this can be approached?

Limiting input to a vba class interface

I am trying to encapsulate the access of an XML configuration file within a (excel) vba custom class. A portion of the XML document is split into 4 or 5 repeated sections that are differentiated by an AreaID. MY question is: How can I limit the input of one of my class interfaces to the various AreaID's that may be read in from the XML document?
revision: what is the best way to control input into a class' interface from within the class (as it pertains to vba)? (i.e. public enum, secondary "helper" class, error handling from within the class, hard-coding...)
I wanted to follow up with #Tim's comment regarding enums and provide some further information as to why enums in the class code may be a good way to limit the input. According to Chip Pearson's site :
Enums cannot be declared within a procedure. They must be declared within the declarations part of a module, above and outside any procedure in the module. Class modules can declare Public Enum types but you cannot create a variable whose type is an Enum declared within a class module.
So as I understand this, if you declare the input on one of interfaces as a (public) enum that has been declared in the class itself, it will limit what values can go in based on that enum. Also the enum will still not be able to be used outside of the class structure.