Update on the “sometimes” constructor

In a previous post I showed how you could create a constructor that a layout could use but no other code could.

Seems that in oder to make this a little more generic and cross-platform you need to look for a different stack entry.

Because macOS and Windows do things differently you can get a very different stack trace on Windows that you would on the Mac. So instead of looking for Window.__Init%%o you should look for the substring ._CreateControls0%%o<

So the updated code in the no parameter constructor looks like

Try
  Raise New NilObjectException
  
Catch noe As NilObjectException
  Dim stack() As String = noe.Stack
  
  // IF this is an instance created on a layout we should find a 
  // ._CreateControls0%%o< in the stack above the call to this
  // Constructor
  // cant look for the whole string as parts of it are the specific  
  // name of the window being constructed which will change by  
  // window name

  For i As Integer = 0 To stack.Ubound
  If stack(i).InStr("._CreateControls0%%o<") > 0 Then
    #Pragma BreakOnExceptions default
    
    Return
    End If
  Next
  
  // and if we do not then raise an UnsupportedOperation error
  Raise New UnsupportedOperationException
End Try

Learning HTML is not the same as learning to write software

At least IMHO they are not equivalent. Why not ?
Html is a design markup language. One focused on layout and presentation. A web designer might use Adobe DreamWeaver to create the specific layout and look of a web site. And never touch a line of PHP, C, Javascript, or whatever language is used to implement the functionality of the web site. Wikipedia points this out on the first line of its entry about HTML where it says

Hypertext Markup Language (HTML) is the standard markup language for documents designed to be displayed in a web browser.

https://en.wikipedia.org/wiki/HTML

Conversely the developer writing the functionality might never touch a single line of HTML or CSS code to make the layout look any particular way. Layout and design are not necessarily their role.

There are however people who are conversant with both the design language (HTML) and add ons to it (CSS) as well as with certain programming languages that can be used on the Web (Javascript). Usually these are in the “front end” or the Web browser. And it’s not unusual to find someone who understand all of these.

Now there are even people who understand all these technologies that are used in the browser and all the back end technologies used to implement the additional functionality of a web site. Usually they’re known as “full stack developers“.

A person like this has learned the language of web designers, generally html and css, some programming languages, php and javscript are common, more than likely some web based framework for various controls and layout like jQuery or Angular, and usually has some knowledge about databases like mySQL or postgresql for the back end.

EDIT : 12:47 I’ve received a comment offline where a confused reader seems to think I implied that one is more important than the other. I make no claim one way or the other and, in software, they both play an important but different role. An ugly app is an ugly app. And one that doesn’t do what it says just doesn’t and so both are required whether its a successful app, web app, or web site.

We expect

Very useful words to keep in the communication between any company and its customers. Its not a promise. Just a rough outline of what things you are planning to do.

Some companies use phrases like this to let their customer base know “hey this is what we think we are going to be able to deliver” without having to promise a specific quarter or date. Sometime things don’t work out as you planned (Airpower anyone ??)

But stating something like this is useful for helping customers understand product direction and what things are more important than others. If you don’t plan to ship something for years then don’t say anything about it until it has a reasonable prospect of being in a shipping product within the next year.

Now there’s ALWAYS the implied “oh but things could come along that waylay our plans”- and that’s the beauty of “we expect to”. Its NOT a promise like if you had said “and it will be available in October”. This is very definite (will) and a promise of when (October).

Googling “microsoft says it expects” or “apple says it expects” you will find a lot of articles that have this phrase in them. These huge companies use this kind of talk all the time to set expectations. And for any company setting & managing expectations is a big deal.

*Edited to correct typos

Add item from clipboard

A post on the forums got me thinking that there might be a way to simply add a whole class, module etc to a project just from code copied from the forums.

So I sat and whipped up a little IDE script that takes a clipboard and will convert it to a class or module. Now there are some tricks. One is that because certain aspects of the Xojo text format can be a bit ambiguous there’s a little more markup involved. Nothing really onerous though.

The following is a simple module

Module Module1
  Sub Untitled()
		  
  End Sub

  Property mUntitled1 As Integer

  ComputedProperty untitled1 as integer
    Get
      Return mUntitled1
    End Get
    Set
     mUntitled1 = value
    End Set
  End ComputedProperty
End Module

When copied to your clipboard and the script is run you get a module on your desktop on macOS. Sorry about this but I haven’t tried this on Windows or Linux yet. And I can’t insert it into the project directly with IDE scripting as it work today 🙁
The following gives a class on your desktop

class TOperInfo
  enum TOperType 
    OperNull
    OperMult
    OperDiv
    OperPlus
    OperSous
  end enum

  property Priority as Uint8
  property NbOper as TOperType

  Sub Constructor( priority as Uint8, nbOper as TOperType)
    self.priority = priority
    self.NbOper = nbOper
  end sub
end class

Enjoy !

Making a constructor sometimes illegal to call

Suppose you write a control subclass that you want people to be able to add to a window layout OR be able to create on the fly. But you want to make sure that when an instance is constructed in code it MUST have a parameterized constructor. However, in order to put an instance on a layout by drag and drop it has to have a no parameter constructor. These two design goals seem very much at odds.

So how do you make this happen ?

Such a control might be like :

Class myControl
  Inherits Canvas

  Sub Constructor()
  End Sub

  Sub Constructor(name as string)
     self.mName = name
  End Sub

  Computed Property MyName as string
    Function Getter() as string
       return mName
    End Function
    Sub Getter(value as string)
       mName = value
    End Sub
   
  protected mName as string
end class

We’ll assume that MyName has been exposed as part of the Inspector Behaviour.

But the class definition above would definitely allow you to write code that called either constructor. How to make it so the no parameter constructor can only be used by instances on a layout that, as part of initializing the layout, basically does the following

dim c as new myControl
c.MyName = "whatever value the user set in the inspector"

But there is a trick you can use to know how you have been called. An exception exposes the call stack to you and you can examine that to know if there is a window being initialized that has resulted in your no parameter constructor being called. And so you can make it so a window being initialized can use the no parameter version. In fact to make it so your control can be placed on a layout in the IDE designer it MUST have a no parameter constructor if it has any constructors.

If we make that no parameter constructor read as follows we can make this raise an exception when used improperly outside of a window being constructed. Sorry can’t make the compiler reject it (THAT would be awesome)

Try
  Raise New NilObjectException
  
Catch noe As NilObjectException
  Dim stack() As String = noe.Stack
  
  // IF this is an instance created on a layout we should find a 
  // Window.__Init%%o<Window> in the stack above the call to this Constructor
  For i As Integer = 0 To stack.Ubound
    If stack(i) = "Window.__Init%%o<Window>" Then
      Return
    End If
  Next
  
  // and if we do not then raise an UnsupportedOperation error
  Raise New UnsupportedOperationException
End Try

A window, when being created, calls __Init and so we can tell if we were called by a window being created or not by walking up the call stack. If there is no Window.__Init in the stack then we definitely were not and so can raise an exception to let the coder know that this usage, without a parameter, is only for Layouts and nothing else.

Sampling with a delay

MacOS terminal is a useful tool to know for a few really handy things.

One is getting a sample of a process after some delay so you can start doing whatever it is you want to sample.

Trying to do this in Activity monitor is not possible

But at the command line you can delay the start of the sample so you have a chance to set up the sampling and then switch back to Xojo to do the task you want sampled.

So how ?

Open Terminal

Once there enter

sleep 5; sample Xojo  -file ~/Desktop/Sample2019r1.1macOS12.6.txt

The number after SLEEP is how many seconds to wait before starting to sample

The SAMPLE command takes several parameters. We’ve told it to look at any process containing “XOJO” and to put the output file on our desktop with a specific name.

This handy bit of bash makes it easy to sample something to send to Xojo as part of a bug report.

Why shadowing should be avoided

We’ll create a sample project to demonstrate why its a bad thing to do.

Start a new desktop project.

Add a new Class that is a subclass of ”CancelButton” by dragging a CancelButton from the library to the Navigator.

Name this new class “myPushButton”

Add a property  to it – enabled as boolean

Make sure the property is public

Now on Window1 add an instance of this new button subclass.

Name it “MyPb”

Now add a bevel button and name it bevTestSubclass.

Change its Caption to say “bevTestSubclass”

In its action event put

myPb.enabled = Not myPb.enabled
myPb.invalidate

Add a second bevel button and name it bevTestBaseClass

Change its Caption to say “bevTestBaseClass”

In its action put

PushButton(myPb).enabled = Not PushButton(myPb).enabled
PushButton(myPb).invalidate

Save (if you care to) and Run

If you push the bevTestBaseClass button the button enables & disables on each push. And it does this visibly.

But if you click the bevTestSubclass button nothing happens.

Why not ?

Properties are not virtual. Quite literally there are two “enabled” properties and they are not the same one. The custom subclass contains one. And the base class contains one.

So when the code knows you are referring to the subclass type the “Enabled” property that is used is the one in the subclass instance. And the framework doesn’t look at this one at all.

So the framework looks at the one in PushButton and redraws with whatever Enabled state that one says.

And its not the same as the one in the subclass.

But when you press the bevTestBaseClass button you do get the change you expected because the cast makes the code refer to the Superclass version of enabled.

This specific use where a cast is involved isn’t so hard to find with a search and replace. But it’s also not the only way that shadowed properties cause problems. The really tricky ones are where the declared type of a variable is the superclass type and then you get much the same behaviour as with the casts. And this one is NOT easy to find.

We’ll demonstrate by adding additional code to the project so far.

First lets define a new method – FlipSubClass – that takes a myPushbutton as a parameter.

Public Sub flipSubclass(button as myPushButton)
  button.enabled = Not button.enabled
  button.invalidate
End Sub

And for good measure we’ll add a new method – FlipSuperClass – that takes a Pushbutton as a parameter

Public Sub flipSuperClass(button as PushButton)
  button.enabled = Not button.enabled
  button.invalidate 
End Sub

The only difference between these two is the type of the parameter.

Now lets add two more bevel buttons to use these new methods.

Add a bevelbutton and name it bevDimSubClass and set the caption to bevDimSubClass.

In this bevel buttons action event put

  flipSubClass(myPb)

Add a second bevel button named bevDimSuperClass and set the caption to bevDimSuperClass

And in this action event put

  flipSuperClass(myPb)

And run.

Note this time there is NO explicit cast required and we can safely pass a myPushButton to a method that takes a PushButton because a subclass IS always also the super class type (isA would be true if you checked myPb isa PushButton)

And yet the bevDimSubclass button has no effect on the buttons appearance but the bevDimSuperClass button does.

Its the exact same issue as before but this time it’s even harder to detect because what natters here is not the actual type or the instance but the DECLARED type of the parameter. 

Since shadowing can cause such hard to track down bugs it better to avoid it.

Now IF you cannot and really to require a subclass have its own “Enabled” property that actually works you should add it as a COMPUTED PROPERTY that in the getter simply casts SELF to the super type and returns the’s supers property value. And in the getter again cast to the super type and set the supers property to that value given.

And here’s a sample that shows the bad version and how to make it work as expected

Follow up on what type am I ?

Back when I was still at Xojo I wrote a blog post about what type of variable am I ?

This is a follow up on that to maybe help explain things more.

The particular difficulty is arrays. They are simple and can cause deceptive an hard to find bugs BECAUSE they are so easy to use and the Xojo language appears to do what you intend (but I don’t think it is doing the wrong thing).

Its why its important to know the difference between a value type and a reference type.

The set up for this is simple. A new Class in a desktop project cleverly named Class1. That class has one public property, values() as variant.

The rest of the code is in the Window1.Open event in a desktop project.

It’s important that you turn on Preferences > Debugging > Show Object IDS in variable lists.

The rest of the code is simply this 

Dim theClassInstance As New class1

Dim emptyarray() As Variant

theClassInstance.values = emptyArray // <<< THIS LINE IS WHAT CAUSES THE HAVOC !!!!
// Because arrays are "reference types" this line does not copy each value in the 
// array into a new array
// it simply sets "theClassInstance.values" to refer to the same array as 
// "emptyarray" refers to
// so altering one looks like it alters the other

// for this example turn on Preferences > Debugging > Show Object IDS in variable lists

Break
// now look at the object ID of emptyarray and theClassInstance.values
// they _should_ be the same which means they are the same object so 
// changing one will appear to change the other

theClassInstance.values.append ( "123" )
Break
// now look at the object ID of emptyarray and theClassInstance.values
// they _should_ be the same which means they are the same object so 
// changing one will appear to change the other

Redim emptyarray(-1)
Break
// now look at the object ID of emptyarray and theClassInstance.values
// they _should_ be the same which means they are the same object so 
// changing one will appear to change the other

emptyarray.append ( "123" )
Break
// now look at the object ID of emptyarray and theClassInstance.values
// they _should_ be the same which means they are the same object so 
// changing one will appear to change the other

Redim theClassInstance.values(-1)
Break
// now look at the object ID of emptyarray and theClassInstance.values
// they _should_ be the same which means they are the same object so 
// changing one will appear to change the other

If you run this code at each break point you can see that if you check the array that was NOT touched in code you will see it has also changed to mimic the other.

This is because arrays are reference types and the line

        theClassInstance.values = emptyArray 

copies the REFERENCE – not the values in the array 

Be careful with your references out there !

Simple but really useful alternate menus

macOS supports the notion of Alternate menus. One that even once you have opened the menu you can toggle between their textual description and short cut by pressing the Option Key or another modifier like Shift or Control.

And you can even set up several so pressing Shift is one, Shift + Ctrl is another, and Option is yet another.

And this is achievable in Xojo quite easily.

I’ve posted a small project that demos this 

Enjoy !

My departure

Originally published on my old blog March 12, 2019

After Joe Ranieri quit* & moved to a new job I think everyone felt stressed. I know I did. It felt like so much more was expected of an ever smaller group of engineers.

By Dec of that year I’d had enough of the forums and some of the general dumping on Xojo as a product. I’d made a post, I forget about what, and decided later to remove it. And I removed a bunch more of my posts.

And that lead to https://forum.xojo.com/44831-norman-s-posts

So my account was altered so I could read but not post delete etc

Fast forward to last week.

Internally we had a Slack question about how everyone learned to code.

I replied as did Dana and others.

Dana mentioned that she’d learned HTML and CSS (I think)

I replied that they aren’t for application coding and and while lots of devs know them those aren’t quite the same.

And there was a reply about how it was expected that maybe a customer might do this “gatekeeping” it wasn’t expected of someone internal.

I replied to the effect “nm forget I said anything”

Later I decided that post was not suitable, nor the gatekeeping one so I removed them. And I was editing my previous one about how I got started and managed to delete the thing. Not sure how but I did. Maybe having a granddaughter around when you’re at your computer is a bad idea. I don’t honestly know but Slack really needs UNDO (maybe it has one and I don’t realize it?)

Anyway it was gone and I didn’t think it was a big deal as I could repost how I learned if necessary and the other two did not need to be revived.

Monday morning I got up. Grabbed a coffee. Sat at my machine. And since I had slept in a bit started Slack preparing for the usual morning meetings we have. 

And there was a message from Travis asking “Hey you there?”

Now he NEVER pings a person before the morning huddle. And I mean never. So this was weird.

I answered him and he called. Right from the outset I had a bad feeling as his tone and what he said made it obvious this was a “Bad Day”

We talked a bit – but it was obvious the decision was already made and out of his hands. I truly had to laugh at the … pettiness … not sure thats the right word .. the sheer insanity of being fired for removing a few posts that I had come to realize probably should not have been posted in the first place. The was a passing mention of “abrasive to customers” or something along those lines but it was obvious that wasn’t THE core issue.

And that is why I’m no longer at Xojo. Deleting posts that I realized probably should have been posted in the first place.

At least thats how I understand things.

Things will, eventually be ok here.

At Xojo I don’t know as the IDE code base, never mind everything else, is large complex and can be very hard to move in any particular direction and NOT break a lot of things along the way.

*Joe continued to work for Xojo on contact for a few months after this because his work on Android wasn’t finished.