Getting a Module DXL Attributes Value from ModuleProperties

I have a Module DXL Attribute with this test code:

obj.attrDXLName = "Just Testing"


It works find except when accessing via ModuleProperties:

 

string AttributeName = "Attr DXL 2"
string ModulePath = "/DXL Context/New Module"
 
ModName_ ClosedModRef = module(ModulePath)
 
if(null(ClosedModRef)) {
    print "Module '" name(ClosedModRef) "' doesn't exist\n"
} else {
        // Get the Module Properties
        ModuleVersion ModVersion = moduleVersion(ClosedModRef)
        ModuleProperties ModProperties
        string Error = getProperties(ModVersion, ModProperties)
        if(null(Error)) {
                AttrDef AttrDefRef = find(ModProperties, AttributeName)
                if(null(AttrDefRef)) {
                        print "Module Attribute '" AttributeName "' in '" name(ClosedModRef) "' doesn't exist\n"
                } else {
                        print("Get via ModProperties:\n")
                        print(ModProperties.AttributeName "")
                }
        }
}


That causes a dxl error in the AttributeDXL: null Object parameter was passed into argument position 1.

So I tried this:

 

 

Module mod = current
mod.attrDXLName = "Just Testing"


and this:

 

 

Object obj2 = obj__
obj2.attrDXLName = "Just Testing"


All cause an error.
I can avoid the error with:

 

 

if(!null(obj)) {
    obj.attrDXLName = "Just Testing"
}


But then still can't read the value via ModuleProperties - because it isn't being assigned a value when queried.

Any ideas?

 


SystemAdmin - Tue Feb 14 07:36:08 EST 2012

Re: Getting a Module DXL Attributes Value from ModuleProperties
Tony_Goodman - Tue Feb 14 08:51:33 EST 2012

You seem to be confused between object and module level attributes.

obj is automatically defined as the current object and can only be used in object level attributes, not at module level.

Did you check the "module" check box when you created your attribute?
And un-check the object box?

// then the following should work for a module level attribute
Module m = current
m.attrDXLName = "Just Testing"

Tony Goodman, www.smartdxl.com

Re: Getting a Module DXL Attributes Value from ModuleProperties
SystemAdmin - Tue Feb 14 09:08:34 EST 2012

Tony_Goodman - Tue Feb 14 08:51:33 EST 2012
You seem to be confused between object and module level attributes.

obj is automatically defined as the current object and can only be used in object level attributes, not at module level.

Did you check the "module" check box when you created your attribute?
And un-check the object box?

// then the following should work for a module level attribute
Module m = current
m.attrDXLName = "Just Testing"

Tony Goodman, www.smartdxl.com

I must have failed to explain properly.

I am using a module level attribute, however...

Module level dxl attributes can be set with attrDXLName and (current Module).
Module level dxl attributes can be also be set with attrDXLName and obj. (Strange but true).

This all works fine, normally.

Neither works however when accessing via ModuleProperties.
In this case (current Module) is null AND obj is null, so the attribute dxl throws an error.

Re: Getting a Module DXL Attributes Value from ModuleProperties
llandale - Tue Feb 14 11:03:11 EST 2012

Scenario: You want an on-demand script that counts all the undeleted objects in the Project without opening all the modules. So you write a module-level DXL-attribute that displays the count of all undeleted objects in the module. The report script uses ModuleProperties to quickly query the count in each module and adds them all up.

As you discovered, when the module is open the "obj" handle for module-level Attr-DXL "correctly" points to the "module" node; if you get the AbsNo it will be zero. And yes, obj.attrDXLName = Results works for module-level attributes. Also, BTW, obj."Prefix" = "New Module Prefix_" also works, but IMO that's a bad idea.

But only if the module is OPEN. Using ModuleProperties on a closed module means you cannot get a Handle on any of its Objects and thus the AttrDXL goes into the twilight zone.

So you cannot cleverly use ModuleProperties to query Module level DXL attributes to avoid the serious lag time of openning all those modules.

So you can query all the "Attributes" of the ModuleProperties, but first you need to know if its an attr-DXL, and if so do not query its value.

the Attr-DXL needs to know if its running "as the module" or "as an Object", as it cannot do something like obj."Object Text" as that attribute doesn't apply to the module.

I played with the idea of having the Module-level DXL attribute query and display whatever the value is, but if the module is open for Edit then it also sets a sibling string attribute to that value, presuming the module will be closed. They you get a psuedo recent value that is queryable with ModuleProperties.

-Louie

Re: Getting a Module DXL Attributes Value from ModuleProperties
SystemAdmin - Tue Feb 14 11:25:58 EST 2012

llandale - Tue Feb 14 11:03:11 EST 2012
Scenario: You want an on-demand script that counts all the undeleted objects in the Project without opening all the modules. So you write a module-level DXL-attribute that displays the count of all undeleted objects in the module. The report script uses ModuleProperties to quickly query the count in each module and adds them all up.

As you discovered, when the module is open the "obj" handle for module-level Attr-DXL "correctly" points to the "module" node; if you get the AbsNo it will be zero. And yes, obj.attrDXLName = Results works for module-level attributes. Also, BTW, obj."Prefix" = "New Module Prefix_" also works, but IMO that's a bad idea.

But only if the module is OPEN. Using ModuleProperties on a closed module means you cannot get a Handle on any of its Objects and thus the AttrDXL goes into the twilight zone.

So you cannot cleverly use ModuleProperties to query Module level DXL attributes to avoid the serious lag time of openning all those modules.

So you can query all the "Attributes" of the ModuleProperties, but first you need to know if its an attr-DXL, and if so do not query its value.

the Attr-DXL needs to know if its running "as the module" or "as an Object", as it cannot do something like obj."Object Text" as that attribute doesn't apply to the module.

I played with the idea of having the Module-level DXL attribute query and display whatever the value is, but if the module is open for Edit then it also sets a sibling string attribute to that value, presuming the module will be closed. They you get a psuedo recent value that is queryable with ModuleProperties.

-Louie

I think you explained it better than I did!
I don't really have a senario in mind, I just noticed it when playing with ModuleProperties.

I considered what you did too - setting a normal Module Attribute from the DXl Attribute, but I don't like doing things like that.

I wondered if it could be read without being run, but since it runs when it is accessed I don't think it is possible.
I guess the null(obj) test should always be used when to setting a value to avoid any DXL Errors.

Re: Getting a Module DXL Attributes Value from ModuleProperties
SystemAdmin - Tue Feb 14 11:31:31 EST 2012

SystemAdmin - Tue Feb 14 11:25:58 EST 2012
I think you explained it better than I did!
I don't really have a senario in mind, I just noticed it when playing with ModuleProperties.

I considered what you did too - setting a normal Module Attribute from the DXl Attribute, but I don't like doing things like that.

I wondered if it could be read without being run, but since it runs when it is accessed I don't think it is possible.
I guess the null(obj) test should always be used when to setting a value to avoid any DXL Errors.

also, I notice there is no:

void delete(ModuleProperties&)


to clean up the variable

Re: Getting a Module DXL Attributes Value from ModuleProperties
Mathias Mamsch - Tue Feb 14 12:35:44 EST 2012

SystemAdmin - Tue Feb 14 11:31:31 EST 2012

also, I notice there is no:

void delete(ModuleProperties&)


to clean up the variable

Hi, I confirm your observations, I have tried the same thing earlier and noticed, that closed modules will not execute DXL attributes. So I would consider that a bug, others might consider that by design, since on a closed module, you neither have an 'Object' nor a 'Module' handle to query. So all your DXL attributes that you would write will fail. Therefore you would need some very bad trickery to make that work.

You 'could' experiment with reading the DXL code from the attribute, to determine if it is a DXL attribute and then write your own 'execute' function by:

  • hooking Attr__ read functions and replacing the calls by querying the corresponding ModuleProperties
  • hooking the Attr__ write functions to get changes to the DXL attribute itself and retrieve the value
  • marshalling the value to the execute function


But I would consider this experimental instead of really putting code like this in any production environment. In the below code I outlined how to go about this - i have to admit I already did something similar to execute Layout DXL manually for a DXL Layout comparison algorithm which worked pretty well. However this is a much more complicated case!

The below code replaces the Module.string operator to actually replace it by a call to ModuleProperties.string which fortunately works the same. You marshal the ModuleProperties variable to the eval context by its memory adress (casting it back in the code). To retrieve the value of the attribute the code also hooks the attribute assignment and instead of marshalling the result out of the eval context it will just print it to be save.

However you can imagine this will only work only for the simplest of DXL attributes. So if your life does not depend on it, just open the module.

 

 

ModuleProperties mp = null
 
// New Module contains a DXL attribute called 'Attr' with a DXL code that does (current Module).attrDXLname = "Hello"
getProperties (moduleVersion module "New Module", mp)
 
// get the attribute definition
AttrDef ad = find (mp, "Attr") 
 
// read the code
string sDXL = ad.dxl 
 
// print the code
// print sDXL
 
// this is our hook code, that will modify the behaviour of the DXL attribute
string sPrefixCode = "
string attrDXLName = \"Attr\"
ModuleProperties mpGlob = ((addr_ " ((addr_ mp) int) ") ModuleProperties)
 
Attr__ ::.(Module m, string s) {
     return (mpGlob.s) 
}
 
string ::=(Attr__ at, string x) {
   print x
   return x
}
"
 
// This is the code we will execute: 
print "Executing:\n"
print sPrefixCode sDXL "\n"
 
// Now lets see what comes out
print "Manually executing the DXL attribute:\n" 
eval_ sPrefixCode sDXL



Maybe that helps, regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Getting a Module DXL Attributes Value from ModuleProperties
llandale - Tue Feb 14 15:06:27 EST 2012

Mathias Mamsch - Tue Feb 14 12:35:44 EST 2012

Hi, I confirm your observations, I have tried the same thing earlier and noticed, that closed modules will not execute DXL attributes. So I would consider that a bug, others might consider that by design, since on a closed module, you neither have an 'Object' nor a 'Module' handle to query. So all your DXL attributes that you would write will fail. Therefore you would need some very bad trickery to make that work.

You 'could' experiment with reading the DXL code from the attribute, to determine if it is a DXL attribute and then write your own 'execute' function by:

  • hooking Attr__ read functions and replacing the calls by querying the corresponding ModuleProperties
  • hooking the Attr__ write functions to get changes to the DXL attribute itself and retrieve the value
  • marshalling the value to the execute function


But I would consider this experimental instead of really putting code like this in any production environment. In the below code I outlined how to go about this - i have to admit I already did something similar to execute Layout DXL manually for a DXL Layout comparison algorithm which worked pretty well. However this is a much more complicated case!

The below code replaces the Module.string operator to actually replace it by a call to ModuleProperties.string which fortunately works the same. You marshal the ModuleProperties variable to the eval context by its memory adress (casting it back in the code). To retrieve the value of the attribute the code also hooks the attribute assignment and instead of marshalling the result out of the eval context it will just print it to be save.

However you can imagine this will only work only for the simplest of DXL attributes. So if your life does not depend on it, just open the module.

 

 

ModuleProperties mp = null
 
// New Module contains a DXL attribute called 'Attr' with a DXL code that does (current Module).attrDXLname = "Hello"
getProperties (moduleVersion module "New Module", mp)
 
// get the attribute definition
AttrDef ad = find (mp, "Attr") 
 
// read the code
string sDXL = ad.dxl 
 
// print the code
// print sDXL
 
// this is our hook code, that will modify the behaviour of the DXL attribute
string sPrefixCode = "
string attrDXLName = \"Attr\"
ModuleProperties mpGlob = ((addr_ " ((addr_ mp) int) ") ModuleProperties)
 
Attr__ ::.(Module m, string s) {
     return (mpGlob.s) 
}
 
string ::=(Attr__ at, string x) {
   print x
   return x
}
"
 
// This is the code we will execute: 
print "Executing:\n"
print sPrefixCode sDXL "\n"
 
// Now lets see what comes out
print "Manually executing the DXL attribute:\n" 
eval_ sPrefixCode sDXL



Maybe that helps, regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

... so long as the module-level DXL attr doesn't access any "Objects" (such as counting objects in the module) or some other module-level DXL-attribute that does.

However, a module-level DXL attribute that doesn't access any Objects must therefore only access other module level Attributes or the existence of Attributes, and since those things rarely change having some non-attr-DXL value to house the info looks appealing.

In any event, putting this in attr-DXL seems prudent, unless you want to run module-level code:
  • if (null obj or level(obj) < 1) halt
-Louie

Re: Getting a Module DXL Attributes Value from ModuleProperties
SystemAdmin - Wed Feb 15 05:20:02 EST 2012

Mathias Mamsch - Tue Feb 14 12:35:44 EST 2012

Hi, I confirm your observations, I have tried the same thing earlier and noticed, that closed modules will not execute DXL attributes. So I would consider that a bug, others might consider that by design, since on a closed module, you neither have an 'Object' nor a 'Module' handle to query. So all your DXL attributes that you would write will fail. Therefore you would need some very bad trickery to make that work.

You 'could' experiment with reading the DXL code from the attribute, to determine if it is a DXL attribute and then write your own 'execute' function by:

  • hooking Attr__ read functions and replacing the calls by querying the corresponding ModuleProperties
  • hooking the Attr__ write functions to get changes to the DXL attribute itself and retrieve the value
  • marshalling the value to the execute function


But I would consider this experimental instead of really putting code like this in any production environment. In the below code I outlined how to go about this - i have to admit I already did something similar to execute Layout DXL manually for a DXL Layout comparison algorithm which worked pretty well. However this is a much more complicated case!

The below code replaces the Module.string operator to actually replace it by a call to ModuleProperties.string which fortunately works the same. You marshal the ModuleProperties variable to the eval context by its memory adress (casting it back in the code). To retrieve the value of the attribute the code also hooks the attribute assignment and instead of marshalling the result out of the eval context it will just print it to be save.

However you can imagine this will only work only for the simplest of DXL attributes. So if your life does not depend on it, just open the module.

 

 

ModuleProperties mp = null
 
// New Module contains a DXL attribute called 'Attr' with a DXL code that does (current Module).attrDXLname = "Hello"
getProperties (moduleVersion module "New Module", mp)
 
// get the attribute definition
AttrDef ad = find (mp, "Attr") 
 
// read the code
string sDXL = ad.dxl 
 
// print the code
// print sDXL
 
// this is our hook code, that will modify the behaviour of the DXL attribute
string sPrefixCode = "
string attrDXLName = \"Attr\"
ModuleProperties mpGlob = ((addr_ " ((addr_ mp) int) ") ModuleProperties)
 
Attr__ ::.(Module m, string s) {
     return (mpGlob.s) 
}
 
string ::=(Attr__ at, string x) {
   print x
   return x
}
"
 
// This is the code we will execute: 
print "Executing:\n"
print sPrefixCode sDXL "\n"
 
// Now lets see what comes out
print "Manually executing the DXL attribute:\n" 
eval_ sPrefixCode sDXL



Maybe that helps, regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Nice.
I love messing about doing stuff like that.
Worth knowing about, if not using.
Thanks Mathias