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?