FINALLY SHIPPED !

2020r1 finally shipped today.

260 days since 2019r3 shipped. A long time between major releases.

For anyone using Xojo for the desktop, not web, this release isnt particularly noteworthy with fixes for the desktop framework.

There are a number of bug fixes to correct API 2 additions made since 2019.

The focus for 2020r1 was Web 2.0 which is a complete overhaul of Web projects.

Conversations I’ve had with others indicate that they expect several dot releases for 2020r1 to correct bugs and issues still outstanding on release day.

The other thing I’ve learned is that many expect that an update of an existing web 1.0 project to a web 2.0 project is more like a rewrite of that app using a totally new tool. This seems to be something of a disappointment that the IDE doesn’t do more work when opening an existing project. I understand Xojo’s rationale but this is disappointing none the less.

Be prepared to use an old and a new version of Xojo side by side to be able to move your project from one version to the next – or just bite the bullet and rewrite the application. Most of the rewriting will be in the UI – and any business logic that is not tied into the UI explicitly _should_ transition reasonably.

All this said, I mostly skipped testing 2020r1 as did many other long time users I talked to, as its focus was in areas that we were not concerned with.

Advocate

noun | ˈadvəkət | 1 a person who publicly supports or recommends a particular cause or policy

verb | ˈadvəkeɪt | [with object] publicly recommend or support

A good read on turning users into advocates

Along with useful links and examples of things that work and also discussions of why they work.

A good read for anyone running a business of any kind.

While you’re out reading have a spin through this one as well

Making keydown events easier to read

I frequently have to look up certain events and read what returning true and false means.

I dont try to memorize this stuff any more.

One thing I do is insert something like

// this makes things semantically easier to deal with 
// and easier to read
Const rejectKey = True
Const acceptKey = False

into keydown handlers and then return rejectKey and acceptKey from whatever code I write. My code then reads like

// number ?
If Asc(key) >= Asc("0") And Asc(key) <= Asc("9") Then
  Return acceptKey
End If
// permits negative numbers being entered
If currentCellContents = "" And key = "-" Then
  Return acceptKey
End If

and its a lot clearer what the intention is

2020r1

I’d originally written this post in May thinking that “Surely Xojo MUST be done by now” and that I could write a quick review post after Xojo released R1 “any time now”.

I wrote that originally on May 11

Its now August – 12 weeks later – and no release yet

Bob asked much the same question in June

He asked nearly 2 months ago.

And no release in sight yet.

As far as I can tell since REAL changed their name to Xojo Inc this is the longest delay in any releases they have had. It does seem to me this could easily be the longest delays in releases they have ever had since REAL Software was founded.

I have had a handful of license holders contact me saying they feel like they have been misled or even, as one put it, “ripped off” having bought licenses around the time of 2019r2/3 and then having received almost no updates since then.

The best advice I can give is “Try the newest release. When it has what you need only then should you buy a license. Otherwise keep your money in your wallet. Do not autorenew. “

Virtual dispatch for computed properties

So what the heck is Norm on about NOW ?

Properties. Specifically computed properties.

Normally you dont want to be shadowing properties and if you do you need to be careful about how you do it so it doesn’t muck up everything. But even when you DO shadow “right” there can still be issues.

And the reason this comes up is because the DECLARED type of an item may be REALLY relevant.

For instance if you have

Class Item
     property Foo as Integer
End Class

Class subItem
  Inherits Item
   
    Computed Property Foo as integer
      Get as Integer
        break
        return Item(self).Foo
      End Get
      Set(value as integer)
        break
        Item(self).Foo = value
      End Set
    End Computed Property
End Class

This can lead to a messy situation.

If you try something like

Dim c As Item

c = New Item
c.foo = 129 // sets Foo directly and never hits a breakpoint in the computed

c = New Subitem
c.foo = 9 

You will not get ANY complaints from the compiler

The local we declared, c, can hold a reference to an Item OR any of its subclasses – since any of its subclasses IS also the super type (thats how inheritance works)

But with properties the DECLARED type matters. Although the debugger knows that, at the end c holds a reference to one of the SubTypes, the PROPERTIES that are accessed are those of the SUPER class in this case (actually what would be correct to say is the properties of the declared type)

And so, because despite a computed property being a lot like a pair of methods, its not treated the same. For instance, if the code above is altered to

Class Item
     Public Sub Foo() as Integer
       break
       return privateFoo
     End Sub
     Public Sub Foo(assigns v as Integer)
       Break
       privateFoo = v
     End Sub

     Private property privateFoo as integer
End Class

Class subItem
  Inherits Item
   
     Public Sub Foo() as Integer
       break
       return super.Foo
     End Sub
     Public Sub Foo(assigns v as Integer)
       Break
       super.Foo = v
     End Sub
End Class

with the same code trying to set and get the value

Dim c As Item

c = New Item
c.foo = 129 // sets Foo directly and never hits a breakpoint in the computed

c = New SubItem
c.foo = 9 

You’ll see a vast different. This time the RUNTIME type matters and the code in the subclass methods DOES get called.

This is because methods, unlike properties, do use dynamic or virtual dispatch (the names get used interchangeably quite frequently) But properties do NOT. so whatever declared type a local or parameter is matters as to which property you might actually be accessing.

Sometimes this is where you need to cast (which kind of breaks the whole idea of using OO anyways since now you end up with big select case statements to handle many supers & subclasses)

IF subclasses computed properties could be handled using the same dynamic dispatch mechanism that methods use it would make it possible to put properties in the inspector behaviour AND have subclass properties overload the super class ones.

Right now you have to pick between one or the other since computed properties can be in the Inspector Behaviour but arent virtual, or you use method pairs which ARE virtual but cant be exposed in the Inspector Behaviour.

Its crummy to have to make this choice at all.

Stepping away

I’ve had several people tell me they are “stepping away from Xojo” at the moment.

Most are users with many years experience in Xojo.

It’s disappointing that its come to this.

Anyone else had this said to them or doing this ?

Dynamic const or not ?

In the IDE you can create constants.

And if you create them as string constants you can set them to be “localized” or not.

This gives you the ability to support multiple different languages in a single build as the localized language files will be saved and used by your application.

But what happens to other kinds of constants if you add different instance values to ? What does the IDE do with those ? And how does it use those ?

Create a new desktop project. Add a new number constant, kWindowMin. Then add set a new instance value for MacOS ANY LANGUAGE and make the value 500. Add another instance for Windows ANY LANGUAGE and make the value 700.

Set the Window1 Width to #kWindowMin

And notice what it does on macOS (or Windows) immediately. Then run it on macOS and Windows.

Note that this is NOT a value looked up at runtime. It’s not determined at runtime like a dynamic language constant is. With a dynamic constant you can change the system language, run and if there is a localization for that language it will show that localization. Stop the app, switch languages and run again and the new language should show.

This kind of constant is looked up in a platform specific way at COMPILE / BUILD time.

Its set AT COMPILE TIME and never again.

They can be handy because in some situations you need a larger window or field size because the default localized values for a language are longer (German tends to be this way compared to English)

And since you can use it for all kinds of values including integers yiu could use it for colors and have a different set of colors you use for macOS or Windows quite easily.

And you can use Booleans. So with settings for transparency its fairly easy to set up one value for macOS to be TRUE – since it supports transparency very nicely – and FALSE for Windows. Then you can assign that constant to those Windows & controls TRANSPARENT property and easily switch between macOS having transparency on and Windows having it off.

Enjoy !

Select case vs if then

And how they work …..

In a bug report I made I posted a tiny sample of code

Dim tokens() As String

Select Case True
  
Case tokens.ubound < 0
  
Case tokens(0) = "End"
  
Case  "Dim"
  break
  
End Select

(Not this code has a known bug in it – Case “Dim” is wrong but it illustrated the bug I was reporting) I’ve used this style for very long sections of code esp where I dont want to clutter it up with extraneous “if then” or “elseif”

But it gathered a curious comment that convinced me the writer of that comment isnt certain how SELECT CASE works. The comment was

I see no sense in the line „Select Case True“, since True is always True. So the error message points in the right direction, correcting this line.

While I understand the reasoning it also happens to illustrate the misunderstanding of how select case works.

The statement that follows select case is known as the Test Expression.

Xojo will then evaluate each case expression and find the first one that matches that Test Expression.

In the case of the code above it will find the first one that has a case expression that is true

It behaves as if the code was written as

if true = (tokens.ubound < 0) then
  
elseif true (tokens(0) = "End") then
  
elseif true = ( "Dim" ) then

end

This sample replicates the same bug as the original BUT this time the compiler correctly complains about the comparison between TRUE and “DIM” (which is what my bug report was about originally)

Select case can be a very handy way to declutter code and remove a lot of “if then” and “elseif then” from your code.

But only if you know how it works.

Class vs Module

Should be a great WWE match up

Really the question was “should I use a class or a module?”

There’s not really global “Oh always use X” answer here.

But usually if you find yourself wiring code that passed data to a method and you have a group of methods that collectively define a “data type” then you probably want a class.

What do I mean by that ?

Suppose you create a structure and put it in a module. And then that module has all kinds of methods that perform some kind of operations on that structure. That really probably _should_ be a class and all the methods in that module methods in the class.

Modules, or namespaces, arent as a mechanism to define a data type. This kind of style is very classical non-OOP design.

There _may_ still be reasons you want to use this style though. Yoi might use it when the data you’re dealing with is used for a declare or other external API and so your choices ARE limited by what declares can accept. There _may_ be other ways to deal with this situation but it wouldn’t be the worst choice to use a namespace in such a case.