Hi I'm using an object with superclass dynamicprops & matlab.mixin.Copyable
Now I would like to now the size (memorywise) of each of the dynamic properties. I tried stuff like whos and getfield. But it seems like I have a very hard time to find something.
I know that people strugle to get exactly this for handle objects, which this is one of them... But I was wondering if somebody has a solution on that nevertheless.
yours
magu_
You could use the properties function to get a list of properties exposed by an object. The same can be done using metaclass. You can then iterate over them and use x.(p) syntax to access each by name (dynamic field names). You would determine the size memory-wise the same way you do any other variable (size/class or whos).
Note that you might need to recursively traverse the properties in case they are containers themselves (objects, structs, cell-arrays).
Related
I am writing a design-time level editor.
I would like my levels to be defined in JSON, and loaded/saved using Json serialization (Probably NewtonSoft)
The issue I have is this:
In order to have the objects be serializable, they cannot be Unity Objects (e.g. ScriptableObject) (and, indeed, I don’t need them to be – except
In order to bind custom editor stuff to the object’s properties, the objects need to be unity Objects.
I can’t figure out what to do – and figured people must be doing something similar, but my Google skills are failing me (and I have googled A LOT!
As a really simple example:
I have a class called Level, with a string field called LevelName
I have an EditorWindow which has a reference the current Level instance
If Level is a MonoBehaviour, I can say
_so = new SerializedObject(_level); and I can bind a field in my UI to the LevelName field
That works fine – but now I want to save the data – but when I try to serialise it I get an error:
NotSupportedException: rigidbody property has been deprecated
This, my searching tells me, is simply because you can’t serialize unity Object.
But if I change Level to be a POCO (i.e. not inheriting from anything) then the binding doesn’t work because _level is not a UnityEngine.Object
I feel I may be missing something really obvious, but for the moment I am stuck and would really appreciate any help or advice.
In C++ I would just compare the memory addresses of both objects. How would I do something similar in MATLAB?
Worst Case would be to have a static variable that iterates in each constructor and every object gets the current value as ID. But is there a better solution?
Thank you in advance.
#Edit:
I'd like to extend this question by assuming I have some given/not changeable classes inheriting handle and overloading eq. If I want to compare two objects of this class can I somehow cast both instances to handle and use the implementation of eq of the super class?
To test that two handle objects a and b refer to the same instance, you only need to use a == b. This is the same as eq(a, b). This is the defined behaviour of == for handle objects. I.e., for handle objects, == tests for equality of instances, not equality of the values within the instances. This is different from value objects.
For this to work you need to be using handle objects (classdef myObject < handle) because it doesn't make sense to test instances of value objects.
N.B. if you also need to get some kind of instance identifier for a handle object, then you need to do something like you describe using a persistent variable. Here's an example. In that case I would make that a base class for all your objects, so you wouldn't have to copy the same code into each class. But that's unnecessary if all you want to do is test two instances.
I'd like to copy all properties from a NSManagedObject over to a "regular" Swift class. I don't want to do this manually, i.e. make a regular class with all the properties for every NSManagedObject and then manually copy all those values.
I do know how to read property names and values dynamically from my managed object, but how to set them on a Swift class in a way that I can then use those values like
mySwiftObject.name
which returns a String or
mySwiftObject.age
which returns a Number (as those are the types on the Managed Object). Custom subscripting and stuff like that came to my mind, but I didn't manage to achieve this... Is there a nice way to do exactly that?
The documentation says this is allowed:
ClassMethod GetContacts() As %ListOfObjects(ELEMENTTYPE="ContactDB.Contact")
[WebMethod]
I want to do this:
Property Permissions As %ListOfObjects(ELEMENTTYPE="MyPackage.MyClass");
I get an error:
ERROR #5480: Property parameter not declared:
MyPackage.Myclass:ELEMENTTYPE
So, do I really have to create a new class and set the ELEMENTTYPE parameter in it for each list I need?
Correct syntax for %ListOfObjects in properties is this one
Property Permissions As list of MyPackage.MyClass;
Yes, a property does sometimes work differently than a method when it comes to types. That is an issue here, in that you can set a class parameter of the return value of a method declaration in a straightforward way, but that doesn't always work for class parameters on the class of a property.
I don't think the way it does work is documented completely, but here are some of my observations:
You can put in class parameters on a property if the type of the property is a data-type (which are often treated differently than objects).
If you look at the %XML.Adaptor class it has the keyword assignment statement
PropertyClass = %XML.PropertyParameters
This appears to add its parameters to all the properties of the class that declares it as its PropertyClass. This appears to be an example of Intersystems wanting to implement something (an XML adaptor) and realizing the implementation of objects didn't provide it cleanly, so they hacked something new into the class compiler. I can't really find much documentation so it isn't clear if its considered a usable API or an implementation detail subject to breakage.
You might be able to hack something this way - I've never tried anything similar.
A possibly simpler work around might be to initialize the Permissions property in %OnNew and %OnOpen. You will probably want a zero element array at that point anyway, rather than a null.
If you look at the implementation of %ListOfObjects you can see that the class parameter which you are trying to set simply provides a default value for the ElementType property. So after you create an instance of %ListOfObjects you could just set it's ElementType property to the proper element type.
This is a bit annoying, because you have to remember to do it every time by hand, and you might forget. Or a maintainer down the road might not now to do it.
You might hope to maybe make it a little less annoying by creating a generator method that initializes all your properties that need it. This would be easy if Intersystems had some decent system of annotating properties with arbitrary values (so you could know what ElementType to use for each property). But they don't, so you would have to do something like roll your own annotations using an XData block or a class method. This probably isn't worth it unless you have more use cases for annotations than just this one, so I would just do it by hand until that happens, if it ever does.
I am using mongodb with java and also morphia.
For my usecase i get collection name at run time. So i have a enum of collection names and based on some value i get the corresponding collection name from enum. My entity annotation is as follows
#entity(EnumName.getCollectionName())
But i get the following error
"The value for annotation attribute Entity.value must be a constant expression"
I am actually returning a constant expression only. Could anyone let me know what the issue is.
You can't use some something dynamic within annotations as those are "compile" time features which can't be changed afterwards. So you can only handle constants which you declared there, Enums and Classes. For this a smart compiler may be able to find out that you handle something which may never change, but most wont and will simply error as soon as they see that you're trying asign some function value to an annotation property.
I don't really understand what you're trying to do, but it somehow looks like you try to use one "generic" entity class for several concrete entities. I think this is really bad design.
If you can tell more details, we may be able to give you a proper solution for your problem.
If you simply don't know what Class you have to operate with at runtime, try this.
Declare your concrete entities and fill your enum with those Classes. At Runtime you can do Datastore.find(Enum.YOURCLASS) and morphia will query your appropriate class.