My time is valuable (Part Deux)

In a great factory one of the huge power machines suddenly balked. In spite of exhortation, language, oil and general tinkering it refused to budge. Production slowed down and the management tore its hair.
At last an expert was called in. He carefully examined the machine for a few minutes, then called for a hammer. Briskly tapping here and there for about ten minutes, he announced that the machine was ready to move. It did.
Two days later the management received a bill for $250—the expert’s fee. The accountant was a righteous man who objected to overcharge. He demanded a detailed statement of the account.
He received this:
To tapping machine with hammer…$1.00
Knowing where to tap ………………$249.00

https://quoteinvestigator.com/2017/03/06/tap/

There are lots of variations on this story.

In a prior post I wrote about being a better developer and learning to be curious. To explore. And trying to solve the problem on your own before asking for help because people’s time is valuable.

And if you’re like me you sell your time to others as part of your consulting work. You also happen to sell your expertise and experience and those definitely are part of the price you build into whatever rates you charge clients.

As a person who makes living selling my time & expertise to others I don’t think it’s unreasonable to ask for fair compensation when I’m asked for assistance.

I’m more than willing to help out but, since I do make a living consulting, I do expect to be compensated for the time I spend working on a project.

And sometimes I’ll give that advice for free. Or I’ll simply charge a small nominal fee that is NOT the full hourly rate I might normally charge. That’s at my discretion.

But there are those who expect that I should give advice on reasonably substantial projects for free. Not because I want to – but because I should; perhaps because I’m a nice guy and it’s only going to be one time. Really. We promise.

What this kind of request is asking me to do is value my time, possibly several hours of it, at $0 per hour.

I’m like all the rest of you. I have bills to pay just like you do. And given the option of working a few hours on something I might get a “Thank You” for versus something I’ll earn my normal rate for I can tell you which I’ll work on.

Just be aware that I often will help out for no charge but the more time I have to invest in a project to provide that help the less likely it is I will do so free of charge.

But please don’t insist that I do significant amounts of work for free “because you’re a nice guy”. I’m sure there are those who might disagree 🙂

More often than not a small bit of advice isn’t something I’m going to charge someone for. But when that bit of advice starts to turn into many hours, or even days, of effort then I just might ask for some fair compensation for my time. If it’s worth asking me for that advice it might also be worth considering that I get compensated for taking the time to provide that advice.

Late fees

I read a really good article the other day from a writer who was having issues with their clients and trying to collect on invoices that were overdue.

Now, I haven’t had to do this sort of thing in a very long time, but it seemed to me that I have run into the same sort of pushback this author got about charging lates fees.

While they had contracts in hand that said the client would pay within a certain time frame and the client missed those contractual obligations to pay on time the client was still objecting to paying a late fee (despite it apparently even being a legal obligation to do so under NY or NYC law)

I’ve run into that as well way back when I contracted to a number of large corporations. Each had stated terms in the contract to pay net 30 (ie I received the payment by 30 days) but each and every one of them simply ignored the signed contractual terms and in some cases only cut a cheque on the 30th day. Unless they physically handed it to me that day, which they usually didn’t, there was no way the mail got it to me that day. To top it off they claimed that the postmark meant that it was “paid” that day. Which was all well and good but the postmarks were always 1 to 2 days later – so the invoice was still paid late in any event. One went so far as to ignore the contractual terms and simply say “Out terms are always net 90” and with held paying me for 90 days. And then they did much the same and cut the cheque on day 90 and put it in the mail. So I’d get paid 92 days after the invoice was sent, which was 62 days after the contractual terms.

When I first sent in an invoice with “Late fees” for the previous invoice they refused to pay the late fee – again despite the contract actually having terms & conditions explicitly stated for this exact eventuality and a stated late fee. Fortunately for me the group I was working for had a manager that pushed the issue and forced the company to pay the late fee AND revise their cheque processing for a lot of contracted individuals so they were paid on time.

Anyone else have a horror story about not getting paid on time and them getting pushback on charging late fees ?

Making platform specific error codes generic

A few threads on the forums have commented that the URLConnection isnt quite as easy to use as many might expect. In particular there are comments about having to know what error codes a platform might return makes it harder to use than it should be.

Normally Xojo hides this level of detail from us.

I was thinking about this problem and have come up with something of a solution that makes it possible to both know the specific error code and yet still write code that is portable.

My solution relies on the fact that, at compile time, numeric constants will take on one of many possible values if you set up platform specific versions of a numeric constant. Its possible to set up a constant with a specific value for macOS, Windows, Linux, and iOS (as well as a couple that are legacy types) as follows :

If you were to compile this code on macOS the Foo constant would have the value 1, on Windows it would be 2 and so on. The nice thing is that code could simply use the symbolic constant Foo instead of having to rely on the specific value. Instead of writing

// is someVariable = Foo on macOS ?
if someVariable = 1 then
   // do whatever should be done 
end if

you could, and probably should write

// is someVariable = Foo on macOS ?
if someVariable = Foo then
   // do whatever should be done 
end if

This is has the added benefit of making your code more robust since a simple change to a constant is all thats required to instead of finding all the magic number 1’s everywhere. But how does this help us to making generic platform specific error codes (which I admit is a bit of an oxymoron ?)

An enumerated value can be set from one of several possible sources. It can have no specific value assigned, have a literal value, an enumerated value from another enum, or a constant.

IF Enum2 is is defined as

Public Enum Enum2
  value1 = 10
End Enum

Enum1 can be defined as

Public Enum Enum1
  value1 // no specific value assigned
  value2 = 99999
  value3 = enum2.value1
  value4 = kConst
End Enum

That we can use a constant is especially notable as we just saw we can make a constant platform specific. So its possible to have an enumerated value that takes on the value of a platform specific version of a constant (but be careful with this as you would not want to have many enumerated values with the same value as that makes them harder to use)

If we defined our enum as

Public Enum kDemoEnum
  value1 = kConstant
End Enum

and the constant as

Public Const kConstant as Number = -1
  OS X, default language, 1
  Windows, default language, 2
end Const  

when we compiled on macOS the value for kDemoEnum.value1 would be 1, on Windows 2 and on any other it would be -1 (the default for the enum)

So now you can make enumerations that give you the flexibility of named values without having to know the specific values AND a generic set of enumerated values that reflect platform specific values taken from constants.

Use carefully.

UPDATE ! – here’s an example

The default app templates

A lot of times people have common code that they want in EVERY application they start working on. And there are a number of ways people achieve this – copy & paste, svn externals, or a whole host of other means.

But there is a much simpler way to start off with all that common code.

Project Templates !

With templates you can not only create new “types” of projects, you can even override the default projects that the IDE starts with when you start a new Desktop, Web, iOS and Console project. So you dont even have to think about making sure you start new projects from your list of Templates. You can just select the Desktop, Web, iOS or Console items in the New Project dialog and your template project with all your common code will be used.

So how to make all this work ? We’ll start by creating a new Template project. Once you see how easy that is it’s a small step to make the IDE use always your template as the default.

A template project will, by design, always be for one of the specific types of Xojo projects. There’s no way to make a single project that is a Desktop, Web, iOS and Console project all at the same time (there is this feature request though). Every template you create will only create one kind of project.

With that in mind let’s create a new template that we can use for desktop projects.

A common complaint is that Desktop projects don’t move from Windows or macOS to Linux very well. Linux uses different default controls sizes and so your very carefully crafted UI that looks fine on macOS and Windows suddenly has overlapping controls and looks awful on Linux.

There is a very handy module from several forum posters who use Linux a lot that resolves this issue. It modifies the normal GTK3 CSS so that the defaults are more in line with those used on Windows & macOS so your design will look correct when run on Linux.

Having a Template would make it so your Desktop projects incorporate this particular module from the outset.

Unzip and open the ModGTK3 project in the unzipped result. The IDE is going to ask you to find the Build Automation item. Press Cancel and a new one will be created. There is no harm here and I’ve asked Jim to upload this file so this minor issues can be resolved.

Create a new Desktop project in Xojo. This will form the basis of our Template. Switch back to the ModGTk3 project and COPY the ENTIRE GTK3 folder from the MODGTk3 project and all contents. A right click on the GTK3 folder and selecting “copy” in the contextual menu works nicely to do this.
Switch back to the new desktop project you created and PASTE into your project.

Add the OPEN event to your apps App instance if it does not already exist.
If it does make the first 3 lines

modGTK3.initGtkEntryFix
modGTK3.initGtkWidgetHeightFix
modGTK3.InitGlobalGTK3Style

Now we need to save the Template. Templates need to be either BINARY or XML projects.

Navigate to the directory next to your executable copy of Xojo and Save the project as a binary or XML project named PiReadyDesktopApplication.

IF you cannot save in the Project Templates location save it to the desktop and move it to the Project Templates directory next to the Xojo IDE executable.

Close the project we just saved and start a new project.

In the dialog presented (shown above) select PiReadyDesktopApplication.

When the project opens there is the new project with all the GTK3 modifications & classes we inserted previously. And if you Save you will be prompted for a new location to save the new project so you do not accidentally overwrite the Template.

To make the IDE use this template as the default every time you select Desktop from the New Project dialog all you need to do is rename the PiReadyDesktopApplication to Default Desktop Project including the spaces (don’t change the file extension). Now every time you start a new desktop project it will be using your template.

And you can do the same for Web, iOS and Console templates.

see 
http://docs.xojo.com/UserGuide:IDE_Overview 
http://docs.xojo.com/UserGuide:Project_Types 

App vs App

App Battles ! Winner takes all. Last man standing and all that !

No – nothing quite so fun (although it can be a lot of fun)

This has to do with the App class at design time vs the App METHOD (yes it’s a method) at runtime.

The app class at design time can be renamed however you want. You could call it “MyApp”. And for most things that would have no impact. But, you’ll note I don’t say for ALL things.

If you start a new Desktop Application and rename the App class to MyApp I can demonstrate where there are differences.

In the new app’s Window1. Open event lets just do something simple like

dim s as string = App.<press tab>

What you should notice is that none of the defined constants autocomplete. The methods and properties of any Application will show. But no defined constants.

This makes sense because the constants do not exist on Application but they do exist on MyApp.

If we add a few properties to MyApp they also won’t autocomplete. Again the App METHOD, at runtime, returns an Application (or Console Application, Service Application, WebApplication or iosApplication depending on the project type)

Again none of the instances that the App method returns define any of the properties we added to our custom Application instance. And so they will not autocomplete.

What’s an App to do ?

We can definitely deal with this.

One way is to not rename the App class in your project – although this wont alleviate all issues. It will just ignore some for a while. And that is, for many uses, OK.

Or we could cast the return value of the App method to be our defined class type with code like

dim s as string = MyApp(App).<press tab>

This is ALMOST always safe – except in the handful of spots that App can actually be NIL – yay !

It may be better to write something like

dim s as string
if App isa MyApp then
  s = MyApp(App).<press tab>
end if

so a nil return from App won’t matter

Either way the confusion comes from the App METHOD and the App class in your project having the same name. This can make it very unclear whats wrong. And then, when you REALLY need to know why this is, if you’ve ignored this until now you wont know why this weirdness exists.

Unless of course you read this post 😛

Implementing the Factory pattern in Xojo

When using the “factory” pattern you should only be able to get a valid instance from the factory and NO other way. Thats kind of the point of the pattern – to reduce the number of points at which instances can be created. Normally in Xojo you might have a module with a method that can create instances, and its the only one allowed to do this. The constructors for the classes the factory method can create should be protected or private so they cannot be directly invoked using New outside the module.

Usually it might look something like (note this code will not compile)

Module People

  Public Interface IPerson
      Public Function GetName() as string
  End Interface

  Public Class Villager
    Implements IPerson
      Public Function GetName() as string
        return "Village Person"
      End Function

      Protected Sub Constructor()
      End Sub
  End Class

  Public Class CityPerson 
    Implements IPerson
      
      Public Function GetName() as string
        return "City Person";
      End Function

      Protected Sub Constructor()
      End Sub
  End Class

  Public Enum PersonType
    Rural
    Urban
  End Enum

  Public Function GetPerson(type as PersonType) as IPerson
  
    select case type
    case PersonType.Rural
      return new Villager()
    case PersonType.Urban
      return new CityPerson()
    else
        raise new UnsupportedOperationException
    end select
  End Function

End Module

An alternative would be to not use an Interface for IPerson but to make it a base class – they end result is similar.

But, you cant do either in Xojo. At least not quite like my code above shows.

If you have a factory method in the module it cannot invoke their constructors. They are only callable by items in the class hierarchy. It has no special means to access the private or protected constructors of the classes it contains.

So you cant easily restrict construction to ONLY the factory method since what you really need is a “module” or “namespace” scope. And that doesn’t exist.

What you need to do is create an INTERFACE for the various classes in the namespace you intend to expose and make the classes in your namespace implement these interfaces. In addition you need to make the interfaces PUBLIC so they can be used outside the module. As well you need to make the classes that implement the interfaces PRIVATE so you can’t actually try and instantiate them outside the module. This has the unfortunate side effect of making it so you can only use the classes in the module via their interfaces. Remember what we really wanted was just to make it so the only legal way to get an instance was to use the factory.

Note that by having to do everything via an interface this means that “properties” are exposed by pairs of getter / setter methods. Fortunately in Xojo this has little semantic impact except that you have to write the code for it.

All code not in the module must use the interfaces as that’s all you have available.

But now because the classes in the module are PRIVATE you can put as many public constructors on them as you desire. They won’t be callable by anything outside of the module so instances cannot be created in ANY way except by calling the factory method in the module.

Module scope would help reduce this work needed to implement the Factory Pattern by making it possible to implement the module’s classes with “module” scoped constructors. This way you could have the factory return any of the parent or subclass instances and you could skip all the interfaces.

A sample of the initial implementation that doesnt work and the fixed version is here

C Unions

An interesting question came up on the forums the other day about how to mimic “Unions” from C.

Turns out I had answered this some time ago – its close but not exactly the same as in C. But it is close enough to be functional and close enough for most uses.

And it’s not mentioned anywhere in the Xojo docs. Not even in advanced topics.

The requirement was a need to be able to interpret a set of data (4 bytes in the forums post case) in one of two different ways. One was as 4 separate byte values, and the other as 2 16 bit values.

In the example I had given previously the need was a common “record” type that had an identifying “record type” byte as the first byte and several other interpretations of the data that followed. In all cases the records were the same total size but their contents varied.

In the example I have the three structures following :

Structure Structure1
  switchCode as uint8 
  rest(4) as uint8
End Structure

Structure Structure2
  switchCode as  uint8
  val1 as uint16
  val2 as uint16
End Structure

Structure Structure3
  switchCode as uint8 
  val1 as uint32
End Structure

Note that each has, in this set up, a byte at the beginning that is at a common offset and that is used to determine which of the three structures is the correct one to be using to interpret the data. In some cases there may be some other indicator or mechanism to know which way to interpret the data.

In this example all structures are defined to be the same total size. This is NOT required. A C union will be the largest of any of the defined union members. So make sure you account for this when you decide what memoryblock size to use for the initial data buffer.

The data buffer is just a memoryblock of whatever size is needed. To interpret the data differently a Ptr is used. And since Ptr’s can interpret the data they point at via a structure we can, once the mb is assigned to the Ptr, now interpret the data using any of our defined structures.

Dim mb As new MemoryBlock(5)

mb.Byte(0) = &h20
mb.UInt16Value(1) = 32
mb.UInt16Value(3) = 254

Dim p As ptr = mb

Dim s1 As structure1 =  p.structure1 // makes it so I can read the
            // data in mb using the fields from structure1
            // but I could use any of the three OR 
            // some other mechanism to figure out which structure
            // to use to inspect the data

Select Case s1.switchcode

Case &h20
  Dim s2 As structure2 =  p.structure2 
// makes it so I can read the data in mb using 
// the fields from structure2

  Dim value1 As UInt16 = s2.val1
  Dim value2 As UInt16 = s2.val2
  Break

Case &h21
  Dim s3 As structure3 =  p.structure3 
// makes it so I can read the data in mb using 
// the fields from structure3

  Dim value1 As UInt32 = s3.val1
  Break

Case &h22  
  Dim struct1 As structure1 =  p.structure1 
// makes it so I can read the data in mb using 
// the fields from structure1

  Dim value1 As UInt8 = struct1.rest(0)
  Dim value2 As UInt8 = struct1.rest(1)
  Dim value3 As UInt8 = struct1.rest(2)
  Dim value4 As UInt8 = struct1.rest(3)

  Break

End Select

Using this technique we can “overlay” the structure onto the raw data in the memoryblock and read it out using the structures fields.
Very handy especially for those cases where you need to read from file formats, memory formats that involve C unions.

About Attributes

A recent feedback case made me think that there may be a real lack of information about attributes.

A lot of people believe that attributes are key value pairs that must have a valid identifier as the NAME and ALWAYS have a quoted string for a value.

This is incorrect.

Attribute name can be quoted strings – meaning you can, by using a quoted string for the name – have names that include spaces that would normally be invalid.

Secondly you CAN have an attribute VALUE that is NOT a quoted string. When you do this the value that you will see at runtime comes from a CONSTANT with the name placed in the value.

An example is here

Coding style

Thomas Templemann wrote a nice blog post about his preferred coding style guidelines.

And most I absolutely agree with.

Except one.

His suggested style is to test booleans simply for the value they hold and not to test for TRUE or FALSE explicitly. He considers testing for TRUE or FALSE bad style. Examples of bad style are :

if hidden = true then ... // bad style
end if
if hidden = false then ... // bad style
end if

Instead he suggests using good names and the following style

if isHidden then ... // good style
end if
if not isHidden then ... // good style
end if

Personally I find that sometimes picking a “good name” so things read like an English sentence can be challenging and that any code you get from someone else may not adhere to the “good name” principle.

As of late I’ve been working in a lot of code written in German. All the variable names, controls, etc are German. And so nothing reads well to me since I don’t read German.

So I prefer a style like

if einigeWirklichSchrecklicheVariablennamen = true then ... 
end if
if a这儿没有发布参数和返回值 = false then ... 
end if

All this said whatever style you use stick to it and use it consistently throughout your code. Use Thomas’s if you like them and they work for use. Or those from BKeeney. Or write your own set, try them out and work with them and tweak them until they make code easier to write AND easier to read and comprehend when you’ve been away from it for months at a time.

Named parameters

Currently when you call a method in Xojo the parameters are matched up starting from the first to the last from left to right. They are matched up based on their position in the argument list.

One thing some other languages support is “named parameters”.

What this allows is a certain degree of flexibility that doesn’t exist with positional parameters like Xojo uses.

For instance in Xojo if you have a method, Foo, with parameters as follows

Sub Foo(a as integer, b as string, c as Date)

you can call it only using the correct types of parameters in the correct order like

Foo(123, "345", new Date)

There are ways, with optional parameters, to modify this normal operations. If that method was defined as

Sub Foo(a as integer = -1, b as string = "", c as Date = nil)

You could call this like

Foo()
Foo(123)
Foo(123, "345")
Foo(123, "345", new Date)

All the parameters are optional and any that are not supplied a default value as shown in the declaration. But everything is still positional. And there are things you cannot do like skip one parameter. None of these will compile.


Foo(, ,New Date)
Foo( , "345" ,New Date)
Foo(123, ,New Date)

So how would named parameters help ? Named parameters can let you say, explicitly, “this value is for this parameter” rather than just matching up by position. For instance out call to Foo might look like

Foo()
Foo( a:123)
Foo( a:123, b:"345")
Foo( a:123, b:"345", c:new Date)

And you might also be able to do something like

Foo( b:"345", a:123 )
Foo( a:123, c:new Date, b:"345")

And not have to worry about the order. And this might let you do something like

Foo(c:New Date)
Foo( b:"345" , c:New Date)
Foo(a:123, c:New Date)

which skips certain parameters in a manner that you cannot do today.

Certainly this would not be a trivial change to Xojo to support positional and/or named parameters. But there are languages that do this.

In the mean time its possible to manually create your own support for “named parameters”.

If we create Foo with two signatures like

Sub Foo(a as integer = -1, b as string = "", c as Date = nil)
End Sub
Sub Foo(paramarray values as Pair)
End Sub

Then Foo could be called as

Foo(123, "345")
Foo(123, "345", New Date)
Foo( "c":New Date)
Foo( "b":"345" , "c":New Date)
Foo( "a":123, "c":New Date)

NOTE that the “names” of the parameters have to be a literal type – in this case a string.

In this set up though we cant use no parameters. So let’s alter the set up to have at least one parameter otherwise the compiler will have an ambiguous overload in the case there are no parameters. It couldn’t distinguish between the call to Foo where it should use all default parameters and an empty paramarray. So now our declarations look like

Sub Foo(a as integer = -1, b as string = "", c as Date = nil)
End Sub
Sub Foo(value as pair, paramarray values as Pair)
End Sub

And we’ll be able to call this like

// these are positional
Foo
Foo(123)
Foo(123, "345")
Foo(123, "345", New Date)

// the use "named" parameters
Foo( "c":New Date)
Foo( "b":"345" , "c":New Date)
Foo( "a":123, "c":New Date)

So we’re on our way to being able to use either positional parameters OR named parameters. Now how do we make use of the overload that supports named parameters to call the one that supports positional parameters ?

In this method we need to

  • make sure we declare one local variable of the same type for each positional parameter
  • make sure we set these local variables default value to the same default values as the version that uses positional parameters
  • process the FIRST pair and all subsequent pairs in the same fashion and assign values to the local variables

Following all those admonitions the code in the version of foo using named parameters looks like

Dim a As Integer = -1
Dim b As String 
Dim c As Date

Select Case value.Left
Case "a"
  a = value.Right.IntegerValue
Case "b"
  b = value.Right.StringValue
Case "c"
  c = value.Right
End Select

For i As Integer = 0 To values.ubound
  
  Select Case values(i).Left
  Case "a"
    a =  values(i).Right.IntegerValue
  Case "b"
    b =  values(i).Right.StringValue
  Case "c"
    c =  values(i).Right
  End Select
  
Next

foo(a, b, c)

There are caveats to this technique though. Positional parameters will be checked by the compiler for type, the “named parameter” version will only be checked that the passed items ARE pairs. The names and values contained by those pairs are variants and so can be anything. And you can pass the same named parameter multiple times since the compiler is unaware of named parameters. And you can’t use “byref” parameters with the named parameter version – you COULD use reference types though.

I’d love to see Xojo support named and positional parameters using a syntax that looks like “pairs” as first presented.

In the mean time this is what we have.