Eduard Lebedyuk · May 17, 2019

Is there a way to get [ Internal, Private ] property?

I have a class defined like this:

Class test.ABC Extends %RegisteredObject   {

Property myProp As %Binary [ Internal, Private ];


Is there a way to get a value of myProp from outside of the object?

I can't modify or extend the class obviously.

1 455
Discussion (8)3
Log in or sign up to continue

Hello Eduard,

For debug purpose , you can try this :

Set obj = {Your test.ABC instance}

Set res = ##class(%Studio.General).DumpObjectFunc(obj)

While res.%Next() { Write !,"Property : ",res.%Get("Name"), !," Value : ",res.%Get("Value") }

Or just perform a zw obj



EDIT : I tested with ##class(%Studio.General).DumpObjectFunc(obj)

We can get value if "myProp" is not an object.

Thank you, ended up extracting this method:

ClassMethod GetPrivateProp(oref, propName) As %String
    Set value = ""
    Set cd=$system.CLS.DumpContext(oref,0)
    Set inst=$piece(cd,"^",8)
    For j=1:1:inst {
        Set pd=$system.CLS.Property(j,oref,0)
        Set ivar=$piece(pd,"^")
        Set slot=$piece(pd,"^",2)
        Set value = $zobjval(oref,slot,0,3,slot)
    Quit value

UPD: Simplified code, thanks to @Dmitry Maslennikov suggestion:

ClassMethod GetPrivateProp(oref, propName) As %String
    Set pd=$system.CLS.Property(propName,oref,0)
    Set slot=$piece(pd,"^",2)
    Set value = $zobjval(oref,slot,0,3,slot)
    Quit value

I'd like to get an Intersystems expert reference to Eduard's method. Would you encourage us to use such methods (like using $piece etc. to get info from inside objects) Thanks, Uri

That's definitely not a recommended practice.

I would say that this is definitely not recommended.  It does violate the intent of the object design.  You are probably not privy to why this was marked private and internal.  Providing a method to bypass that could create problems.  Of course if this is only for debugging a class that you don't have the ability to edit it may be acceptable.


There, a version with multidimensional array support until 4 subscripts level : 

ClassMethod GetPrivateProp(
   ByRef result As %Binary) As %String
   Do ##class(%Studio.General).DumpObjectExecute(.arr,.oref)
   Set key = $o(arr(propName),1,value), @propName = arr(propName)
   For  {
      Set subscriptLevel = $Ql(key)
      If subscriptLevel=1 {
         Set @propName@($Qs(key,1))=value
      }ElseIf subscriptLevel=2 {
         Set @propName@($Qs(key,1),$Qs(key,2))=value
      }ElseIf subscriptLevel=3 {
         Set @propName@($Qs(key,1),$Qs(key,2),$Qs(key,3))=value
      }ElseIf subscriptLevel=4 {
         Set @propName@($Qs(key,1),$Qs(key,2),$Qs(key,3),$Qs(key,4))=value
      Set key = $o(arr(key),1,value)
   Merge result=@propName
   Kill @propName
   Quit:$Quit arr(propName) Quit

Can be easier:

ClassMethod GetPrivateProp(
  propNameAs %String

$system.CLS.Property accepts property by name as well, so you don't need loop