Implicit Instance is Evil

Xojo has had Implicit Instances of Windows and WebPages from the very beginning and I was so happy when they gave us the option of using it or not.  I can tell you from experience debugging newbie apps that Implicit Instance is evil because it often leads to subtle and hard to find errors.

The implicit instance lets us do some very simple things like:

window1.show

Window1 is shown.  No big deal.  For simple apps this is no problem and fast and easy.  That simplicity comes with some perils because window1 loads whenever any control or property on that window is checked.

For example, a lot of developers will do something  like this:

window1.close //close the window

if window1 <> nil then
   
   //Window is open.  WTF!  I just closed it!
   
end

The problem is that simply by doing this comparison, window1 is loaded into memory and depending on the other window settings it may become visible.  It drives developer crazy.

Setting ImplicitInstance = false forces the developer to make a new instance of Window1 if they want to use it:

dim w as new Window1

w.show

I think this is the preferable approach because it’s safer.  It will never give you Window1 by accident.  In fact, if you attempt to do this with window1.implicitinstace = false:

if window1 <> nil then
   
   //Do something.
   
end

The Xojo compiler will give you an error that says:  Expected a value of type class Window1.Window1, but found a static namespace reference to class Window1.Window1.  This is a roundabout way of saying you can’t call window1 directly since that’s the class name when in reality you need to be checking for an instance of the class. That class instance cannot be named Window1 (because that’s the class name).

So how would you check to see if a Window is already open?  That’s easy.  The Window and WindowCount methods are there for you to do just that.  Iterate through the window listing and when you use the ISA method to ask if it’s of type Window1.  If it is, then do something.

  for i as integer = 0 to WindowCount-1

if window(i) isa Window1 then
   
   //Do something with the Window1 instance.
   
   //You have to cast it as Window1 from the Window method
   
   dim w as window1
   
   w = Window1(window(i))
   
   w.someproperty = false //set a public property
   
   w.LoadNewData //call a public method
   
   w.show //brings the window to the front
   
end

next

A common thing to do is close all instances of a particular window.  Using the above code might fail if you have multiple instances of a window open.  Here is the code that closes all instances of a type of window.

  for i as integer = windowcount-1 downto 0

if window(i) isa Window1 then
   
   window(i).close
      
   end
   
next

In this case we must iterate backwards through the array.  Think about it if you are confused as to why.  Better yet, test it yourself.

Web apps have a similar property in the WebSession.PageCount and WebSession.PageAtIndex methods.

  for i as integer = 0 to session.PageCount-1

dim w as WebPage = Session.PageAtIndex(i)

if w is a WebPage1 then
   
   //do something with WebPage1
   
end

next

The drawback, if you can call it that, to having Implicit Instance = false is that as you call new windows or web pages you haven’t done anything to the old ones.  Depending upon your application this may cause long term memory issues especially as the app gets a collection of pages that are no longer used.   For short lived apps this usually isn’t a problem.

To solve this you can either iterate through the existing windows/pages to find the one you’re looking to reuse or simply close it as you open your new one.  Either way, I don’t think the burden is too high.

It is my not-so-humble opinion, that leaving ImplicitInstance = true is bad for you as a Xojo programmer.  Simply put, Implicit Instance is evil and you should avoid using it – especially in larger applications.

What say you my Xojo developers?    Do you like to turn Implicit Instance off or do you even care?

7 thoughts on “Implicit Instance is Evil

  1. //Give affirmative response to post
    Dim StrResponse as string
    For i as integer = 1 to 1000
    StrResponse = StrResponse + “Yes! ”
    Next
    Return StrResponse

  2. Very interesting post Bob. I LOVE having Implicit Instance ON. I think that comes from my FileMaker background where layouts always exist. In Xojo, I use the fact that Windows / Pages / Views already exist to my benefit. For instance, in the Xojo Web Apps that we’re writing to replace expensive FileMaker solutions, a user can jump from a Customer Page to an Invoice Page and back again without having to reload the data. Of course, I can check to see if the record data changes and update it if I want too…

    • If you understand the implications of Implicit Instance they’re fine. I have found that many developers don’t understand those implications so subtle and insidious bugs creep in. Debugging is simple: Turn Implicit Instance off and see where the compiler squawks. 🙂

      • I am with HAL that I like the Implicit instance of windows, or at least certain windows. WHY? I am a lazy programmer. For some of my apps, certain windows have to be unique (only one (or less) instances of that window). Now I could write a method that checks for its existence and displays the current one or generates one if it doesnt.

        Now for windows that I can open multiple times (presumably with different data in them), I turn it off. So I am probably 50/50 on the use right now.

        After reading this, I will probably work on making it closer to 100% non-instance like you suggest.

        • Interestingly, yesterday we were using a the scrolling container method for a list view and were having problems closing the containers to make the containers go away. This post was in my head and we ended up switching the parent container from an implicit instance to a property so we could just destroy it!

          I have a feeling that like Scott, we’ll be using non instances too…

          Thanks again for this post Bob!

  3. Yes, yes, yes. I always turn it off, and usually use a shared method like Present or something. This way I have to explicitly show/create the window. I also like to have my controls private.

Comments are closed.