Computed Properties

Computed Properties have come up several times in the past week and in both cases, the person I was talking with was having a hard time understanding them.  They are a useful tool in Xojo in the right circumstances.  So let’s dig in.

First, let’s get this out of the way.  You don’t need to use Computed Properties.  Ever.  If you don’t want to.  They are an automation feature of the Xojo IDE.  Simply, they are a lazy way to create getter and setter methods for a private property in your class.

There are times when you want to expose your private property to the outside world but not give it unrestricted access.  Usually you’d want to do this because you need to validate the input, or perhaps something needs to be done before it can be read.

Creating your private property is no problem.  In this case we’re creating moSecurity that is a reference to our clsSecurity class.

Private moSecurity As clsSecurity

You create a Getter method that checks to see if we’ve already created an instance of it.  If not, then you load it and then simply return it.  Simple enough.

Function Security() As clsSecurity
   
   if moSecurity = nil then
      
      moSecurity = me.LoadSecurity
      
   end
   
   return moSecurity
   
End Function

If you want to change the Security object, you create a Setter method and use the Assigns keyword like this:

Function Security(assigns oSecurity as clsSecurity) As boolean
   
   if oSecurity <> nil then
      
      if me.CanChange(oSecurity) = false then
         
         return false
         
      end
      
   end
   
   moSecurity = oSecurity
   
End Function

Again, not terribly difficult to do.  It’s one property and two methods.  Notice that I didn’t name them GetSecurity and SetSecurity because I want these methods to act like a property to the outside world.

Return valuesThe Xojo IDE tries to be helpful by making a hierarchy of the methods that have the duplicate name.  You may (or may not) find this to be terribly useful.  I happen to dislike it because I can’t tell at a glance what the return value is, if anything, on either method without hovering my mouse over it or clicking on it and looking at the Inspector.  But then this is true of ALL functions – not just these types. Just one of the things that I miss from the Real Studio IDE.

SetterGetterMethods

Now repeat this sequence for every private property that you need to have exposed with Setter and Getter methods.  It’s not that it’s hard, it’s just tedious.  And if you have a particularly large class (think Formatted Text Control) that has hundreds of properties, the Method list gets HUGE.  The other drawback is that I often forget to use the Assigns keyword so I get compile errors if I attempt to use the Method as a property.

Computed Properties is a way to help make this a bit easier  We can accomplish the same thing by creating a public property called oSecurity in clsUser.

oSecurity As clsSecurity

ConvertToComputedPropertyPopupRight click on it in the Navigator and choose Convert to Computed.  You’ll see that the IDE makes a Private property called moSecurity as clsSecurity AND creates a hierarchical group for oSecurity containing a public Get and public Set method.  The default code that is in these computed properties is:

 

 

 

Get
   
     return moSecurity
   
End Get

Set
   
   moSecurity = value
   
End Set

At this point, we can modify these Get and Set methods to almost what we had before.

Get
   
     if moSecurity = nil then
   
   moSecurity = me.LoadSecurity
   
end

return moSecurity

End Get

Set

if oSecurity <> nil then
   
   if me.CanChange(oSecurity) = false then
      
      return
      
   end
   
end

moSecurity = oSecurity

End Set

ComputedPropertiesNotice that in the Computed Property version of the set we can’t return a value.  This is probably the biggest drawback, in my opinion, to using Computed Properties.  It’s almost the same amount of work but we have potentially saved some typing and we no longer have to worry about the assigns keyword because the IDE is automagically adding it for us behind the scenes (remember, we all want to be lazy programmers, right).  Thus our property is still treated as a property to the outside world.

One of the things that annoys me about Computed Properties is that now you have double the amount of Properties.  In the old fashioned (setter, getter) way you get a bunch of methods and in this second way double the number of properties.  Both, however, do mostly the same thing.

In my own fantasy world (believe me, it’s scary sometimes) I’d love to have the IDE group Public, Protected, and Private constants, methods, properties, etc so that I can expand only those that I want.  In this case I’d prefer to see only the Public ones.  The drawback is that you would have an additional hierarchy layer that causes clutter and may cause some confusion.  Would having the ability to hide certain scope types help?  I don’t know.

Do I have a conclusion?  Setter and Getter methods for your properties is easy enough.  It takes a little bit more work to set up and a bit more typing.  Each method, however, makes the Navigator a bit harder to read because of the added hierarchy but then so does the Computed Property.

Should you switch to using Computed Properties?  Only you can answer that.  I guess the only thing I’d recommend is be consistent throughout your project.  Consistency makes programs easier to read.

What say you, Xojo programmers?  Do you like using Computed Properties?  Why or why not?

11 thoughts on “Computed Properties

  1. I stopped using Computed Properties at all roughly a year ago. The problem is, that you can not override them. This is mainly a problem if you want to subclass a built-in class, especially controls and you want to capture changes on built-in properties.

    An example: Listbox. If you need to react to the change of the ListIndex property, you use the Change event. If you need to react to the change of the Enabled property, you can’t.

    Well, you can actually. By shadowing Enabled with a Computed Property of the same name. But this is dangerous. To call a shadowed Computed Property you need to cast an object to the subclass implementing the Computed Property – if you forget to do that, the one on the parent class will be called. For an overridden method the one of the subclass will be used, period.

    Some languages like VB.NET offer the opportunity to make a Computed Property overridable. You have keywords clearly stating what you want to happen like Overridable and Shadows. Neat.

  2. If you want overrideable computed properties, have them call a method.

    Amazing – I give into the odd temptation to have a look and see how the old RB community is going and I get to see that they rolled out yet ANOTHER radical rewrite of the IDE that lost functionality expected in any IDE of the last ten years? (display return types).

    sigh

    In the old RB and in C# I have found computed properties very useful. It’s one of the reasons I had them as a core feature in my OOFILE database API back in 1992.

    • Long time no see, Andy! Hope things are going well for you.

      I am not a fan of the Navigator for lots of (controversial) reasons. However, I recently had to go back to an old Real Studio project and I have to admit it seemed archaic and out of date. So while the Real Studio IDE works better in some ways, the Xojo IDE works better in others. If I could only get a compromise between the two I’d be happy.

      Xojo is still alive and kicking. It’s still one of the best cross-platform solutions out there. And of course the people are still outstanding.

  3. One big difference is that PROPERTIES (computed & non-computed) can be viewed in the debugger where a pair of methods can’t.
    There are some drawbacks since the getter can can have side effects.
    The debugger just calls the computed properties GET method to display the item in the debugger.

  4. Just yesterday I added debugging computed properties to a class. I prefix them with Debug, they pick from some objects referenced some values and show them right in debugger when I look on the main class.

Comments are closed.