Last night the northern lights were out in full force.
Walked to the end of the deck and WOW !
We took some pictures but they didnt come out nearly as nicely as the ones my youngest took (like this)

Truly an awesome display
Last night the northern lights were out in full force.
Walked to the end of the deck and WOW !
We took some pictures but they didnt come out nearly as nicely as the ones my youngest took (like this)
Truly an awesome display
Code reuse is an admirable goal for any developer.
Being able to re-use well written well tested code is a good thing.
Especially if you can reuse it across multiple facets of one project, or across several projects.
And I wouldn’t be surprised if a lot of people start out reusing code using copy paste from one place to another.
However, copy paste isn’t usually a well regarded code reuse technique.
Why not ? Stack overflow wrote a blog about the reasons. You might copy & paste someone else’ insecure code into your projects and thereby introduce security vulnerabilities. That’s certainly a possibility.
But what if you’re just copying & pasting your own code around ? Where’s the harm ?
Suppose you have some code you really think is top notch. And you want to reuse it over & over. Suppose you want to reuse it in the event handler of numerous controls across several projects in Xojo.
And sometime later you find there’s a bug in it.
Now how many places do you have to fix in one project ? Or worse across many projects ?
This is where copy paste as a code reuse technique can cause you extra work.
You have to find & fix all that code in every project you’ve used it in.
I’ve been using externals in SVN (yes I still use SVN)
And in every project that uses these shared modules its a simple “update” and they have all the latest code from all the shared items.
Git has similar capabilities.
Some time ago Bob had said he would let the domain registration for BKeeney Briefs lapse. Today it finally came home to roost.
Trying to visit gets you one of several things.
What I got was a domain name squatter site trying to sell me the name.
Sad to see that finally happen but with Bob’s employment changing from contractor to full time employee its not surprising.
And, with this change, another one bites the dust somehow seems strangely appropriate.
Thanks for everything Bob !
Was tracking down a bug in my app and couldnt figure out what was wrong initially.
All the code seemed right but setting a value to code like
value = string.ToInteger
seemed to be the culprit. Sure enough the string contained a value like 3.0e+2 (an integer expressed in exponential form) But the docs say
Method
Returns the integer equivalent of the source string. This function is the same as the Val function but is international-savvy.
But experience was telling me this wasnt true
So a quick test in 2021r2.1 with
Dim s As String = "3.0e+2"
Dim i1 As Int32 = Val(s)
Dim i2 As Int32 = s.Val
Dim i3 As Int32 = s.ToInteger
Break
shows that indeed i1 = 300, i2 = 300, and i3 is 3 not 300 like I would have expected. I changed my use of ToInteger to Val and things work as expected.
Be careful out there
EDIT : reported bug http://feedback.xojo.com/case/65567
If youre one of the people who didnt get the Xojo Experience survey there’s one thats a lot alike at INN
On the forums someone is looking for a way to identify what kind of file they are dealing with. And then a way to “sort” knowing those types.
The suggestion given is to look at each extension in a simple way
But, you can get away without ever having to look at the extension. Folderitem already assigns a TYPE IF there is a filetype defined that matches.
You can use this built in ability to do many things.
I posted about this on INN along with a sample project
Ever think to yourself “Oh I have this project to do and I’ll just cut and paste the code from there and tweak it?” And now you have two copies that are a lot alike but maybe not exactly the same.
And then you do this over & over and now you have many copies of that code?
How do you deal with issues when you find them ?
Which copy is the newest & the most correct ? And which one is the right good copy to use as the basis for yet another copy ?
I’ll admit that I will copy & paste code to examine it. Play with it to see how it breaks. And then I throw it away and fix the real single working copy that IS the master for all others.
And there are some neat tools for this like Snippets for BitBucket Server
Copy & paste coding is fast. Repetitive. And it has issues. Which is why copy-paste programming is used mostly as a negative comment on coding style.
If you have the ability to avoid it by using submodules, includes, sub-projects in whatever version control system you’re using (you ARE using version control right?), or similar mechanisms I’d encourage you to do so.
It will help you avoid the proliferation of many different versions of the same code in all your projects.
And when you need to fix the code you can fix one copy and all your other projects can be updated with it.
A long time ago I was in a BEd\Bsc program at University.
It was supposed to end with me having two degrees. One Degree in Education and one in Computer Science. But the two faculties couldn’t agree on the course of studies over 5 years. And when I got to year 5 it turned out both expected me to do at least one more full year in each faculty. I wasnt financially in a position to do that and had to decide which to finish. Since I had more credits towards my BSc at that point I finished that. But I did have the better part of 3 years of a BEd under my belt as well.
One of the things that came up for discussion during that education was “labels” and how they affect not only the person(s) being labelled, but also the person who applied the label. If you thought of a kid as “slow” or “stupid” or some other negative term, then you, as their teacher, were more likely to react and treat them in accordance with those labels. And you could inadvertently contribute to that child being treated as “slow” or “stupid”. How you perceived them had a direct impact on how you treated them.
If instead you thought of this student as “smart” and “capable” that too could factor in to how you treated those students.
The best defence was to realize when you were doing this and ACTIVELY work to combat doing this. (This article is VERY good on what to do and how to avoid it)
This sort of thing occurs a lot. We probably all do it from time to time. We label people in various ways. Kind. Considerate. Jerk. A-hole. You name it.
The trouble with applying such labels is that once they are applied they tend to stick. And this assumes that whatever behaviour was labelled is permanent, unchangeable and fixed for all time.
A single clumsy attempt at a joke could end up getting a person labelled as a jerk. And the person applying that label remembers that forever and treats that person as “a jerk” from then on. And never bothers to attempt to ever see that person they labelled in any other way. They were “a jerk”. They are “a jerk”. They always will be “a jerk”. Period.
The trouble is that it’s not realistic. People can in one moment be jerks, and in another extremely considerate, caring and compassionate. Rarely are people ALWAYS some singular label. People ARE complex and labels are often too simplistic. Especially if they are applied rigidly and NEVER re-examined to see if the reasons we labelled that person that way. Re-examination is hard because its very likely we base that re-examination ON the labels we have already applied.
The other downside to labels is that the person applying the label can use that label to dismiss the other person. Whether its complaints, concerns, or whatever its easy to see how labelling someone a jerk leads to “so I dont have to listen to them or try to understand their concerns – they’re jerks !”
And since “they’re jerks” everything is seen through that lens. Reasonable criticisms are seen as “Its by that jerk so I dont have to listen or even try to see IF they have some legitimate reason for that criticism. They’re jerks !”
I’ll admit that I do get frustrated with people and complain about them.
Esp as I drive (ask my wife) I do try to avoid labelling people – but its not a 100% success rate.
And, to be honest, I expect that the people this post is meant for might not read it.
Because they have applied a label which they feel gives them permission to ignore this.
Because that single fixed label that requires no thought, no reexamination, or consideration of anything that other person says, thinks, or does.
Sometimes you want classes to have a common API.
But rather than adding a common super class or interface to define that common API, you just make sure your classes have the same methods, events, properties & whatever else you feel is necessary to make them have “the same API”.
I would suggest you rethink doing this.
If what you need is controls that are similar but have differences in them just making it so you have common methods names, properties, and events will make trying to write any common code that can manipulate these controls a pain in the read end to create, maintain, and update.
For instance, lets suppose we create two controls that do wildly different things. One is a canvas control subclass that draws itself in whatever color set with a blue frame. The other draws the frame in in red. (This example is exceeding simple just to illustrate the issues. Its worse with more complex classes & controls)
So we have
Class BlueCanvas
Inherits Canvas
property myfillColor as color
Sub SetFill(newFillColor as Color)
myfillcolor = newFillColor
End Sub
Function GetFill() as Color
return myfillColor
End Function
Event Paint(g as graphics, areas() as
g.forecolor = myfillColor
g.fillrect 0,0, g.width, g.height
g.forecolor = &c0000FF
g.drawrect 0,0, g.width, g.height
End event
End Class
Class RedCanvas
Inherits Canvas
property myfillColor as color
Sub SetFill(newFillColor as Color)
myfillcolor = newFillColor
End Sub
Function GetFill() as Color
return myfillColor
End Function
Event Paint(g as graphics, areas() as
g.forecolor = myfillColor
g.fillrect 0,0, g.width, g.height
g.forecolor = &cFF0000
g.drawrect 0,0, g.width, g.height
End event
End Class
So our two controls have “the same API”
Same events, same methods, same properties of the same type & name.
Lets see what happens when we try to write code that uses these two simple controls.
Suppose we’d like to write a single method that can change the fillcolor of either control
Sub AlterFillColor(ctrl as Variant)
Dim c As Color
If SelectColor(c,"select a color") Then
If ctrl IsA BlueCanvas Then
BlueCanvas(ctrl).myFillColor = c
BlueCanvas(ctrl).Invalidate
Elseif ctrl IsA RedCanvas Then
RedCanvas(ctrl).myFillColor = c
RedCanvas(ctrl).Invalidate
End If
End If
Note several things. The parameter passed in has to be something generic – but it cant be a BlueControl or a RedControl as there is nothing really common between them. We could pass a Canvas but that would not change the code in actual method.
We MUST check to see, in this case, exactly what type was passed in because we cant be sure an appropriate type was passed in. Even if we used a Canvas we’d have to check because a generic Canvas may not have the myFillColor property and trying to access that would cause compilation errors. If we use Variant anything can be passed in. If we make that parameter an Object any INSTANCE of ANY class, not JUST our labels, can be passed in.
We MUST cast, either one time and assign to a temporary we reuse , or on every line of code where we use the control.
And this is one VERY short method and it already looks messy.
How about adding a button to copy the value of myFillColor from one canvas to another.
If we add one button to copy from the bluecanvas to the redcanvas, and another to copy the other way we can copy directly from one to another using something like :
RedCanvas1.SetFill( BlueCanvas1.GetFill() )
or
BlueCanvas1.SetFill( RedCanvas1.GetFill() )
This isnt so bad. But, being the clever sort we are we decide to write a generic “copy from one to the other” method and reuse the heck out of it (and this is where your spidey sense should really go crazy !)
Public Sub CopyFill(fromCtrl as variant, toCtrl as Variant)
Dim copycolor As Color
If fromCtrl IsA BlueCanvas Then
copycolor = bluecanvas(fromctrl).FillColor
Elseif fromCtrl IsA redCanvas Then
copycolor = redcanvas(fromctrl).FillColor
End If
If toCtrl IsA BlueCanvas Then
bluecanvas(toCtrl).FillColor = copycolor
Elseif toCtrl IsA redCanvas Then
redcanvas(toCtrl).FillColor = copyColor
End If
End Sub
And from the outset we have the same issue as above
Except now to manipulate two items we need to do several checks to see what types the from and to controls are.
So despite these “having the same API” thats of no real value since you have to cast and check all the time. And your parameters to methods have to be some more generic type like variant or some common super that still leaves you needing to cast all the time.
Worst of all you can pass ANY parameter that is of the right type. The compiler cannot help you check that your code is correct since it cant do type checking.
Now what if we decide we want to add a … YellowCanvas !
You can go back and see for yourself how many places we have to adjust to handle this “new” type. Every place we have a cast is a potential place we need to add code to.
And every place we add code is a new place for new bugs to crop up.
So how can we solve this in our little example ? I’m sure many of you have already seen the answer. In this case an interface ISNT of use since we can’t define events and properties.
But a common base class, even one that CANNOT be created directly, is of use.
Class FramedCanvas
Inherits Canvas
property myfillColor as color
Sub SetFill(newFillColor as Color)
myfillcolor = newFillColor
End Sub
Function GetFill() as Color
return myfillColor
End Function
Private Sub Constructor()
// makes it so you cant place instances on a layout
// or create them direcly
End Sub
End Class
Class BlueCanvas
Inherits FramedCanvas
Event Paint(g as graphics, areas() as
g.forecolor = myfillColor
g.fillrect 0,0, g.width, g.height
g.forecolor = &c0000FF
g.drawrect 0,0, g.width, g.height
End event
End Class
Class RedCanvas
Inherits FramedCanvas
Event Paint(g as graphics, areas() as
g.forecolor = myfillColor
g.fillrect 0,0, g.width, g.height
g.forecolor = &cFF0000
g.drawrect 0,0, g.width, g.height
End event
End Class
Now our classes dont just have the same API because we happened to write them that way. They have the same API by definition. They cant NOT have the same API.
Now our method to set a fillColor looks like
Public Sub AlterFillColor(ctrl as FramedCanvas)
Dim c As Color
If SelectColor(c,"select a color") Then
ctrl.FillColor = c
ctrl.Invalidate
End If
End Sub
Note we CAN use the super class as the TYPE for the parameter. BlueCanvases are also FramedCanvases. As are RedCanvases. But a regular canvas control could NOT be passed in (unlike before) and we do not need to do any casting etc. The compiler CAN check for us what is passed in. So our reliability and likelihood of writing bug free code is improved.
And, note, we have LESS code than before. And even if we add YellowCanvases etc we do NOT need to alter this code. Thats a good thing.
Directly copying the fill color from one control to another still works about the same
BlueCanvas1.SetFill( RedCanvas1.GetFill() )
BlueCanvas1.Invalidate
or
RedCanvas1.SetFill( BlueCanvas1.GetFill() )
RedCanvas1.Invalidate
What about our method based copy that we want to just reuse like mad ?
Public Sub CopyFill(fromCtrl as FramedCanvas, toCtrl as FramedCanvas)
toCtrl.FillColor = fromCtrl.fillColor
End Sub
Its trivial. No casts. No need to alter it every time a new sub type of framedCanvas comes along. And unlikely to ever have a bug.
Why ? Because these controls have an EXPLICIT API that forces them to be the same. Its not just because I happened to write the same code in several of them but because BY DEFINITION they are the same.
Where’s this all leading ?
Well so far this has all been simple and in a desktop app. It could just as well have been in a web app, iOS or some other app type. But the PRINCIPLES hold true even if you wanted to extend this to be across all those app types.
Suppose the hierarchy defined was
Control
- common control events, method & properties
RectControl
- common rect control events, method & properties
(for controls bound by a bounding box)
Button
- common button events properties & methods
DesktopButton
- events properties & methods specific to the desktop
WebButton
- events properties & methods specific to the web
iOSButton
- events properties & methods specific to ios
Canvas
Listbox
TabPanel
PagePanel
and so on
Now its plausible to write a method that regardless of whether it was used in a desktop, ios, or web project that could locate a Control, Rectcontrol, or Button. Or any other control that is defined.
No casting required.
There are some compatibility details. The DesktopButton would have to have its flags set to only be in desktop projects, the web ones only in web projects, etc. That would solve trying to compile a desktop project with iOS or web controls & vice versa.
The same may be true for controls that only exist on the desktop, and have no counter parts elsewhere. But those flags can be set at any level in the hierarchy.
And the IDE could check those flags to see what things ARE compatible and not allow you to use ones that arent.
The other upside with a properly laid out hierarchy like this for EVERYTHING is that it BY DEFINITION it tells you what properties you could expect to carry over if you copied a desktop button and pasted it into a web project. Nothing that is desktop specific should, or could, make sense in the web one. But anything defined in BUTTON and higher up in the hierarchy would, or should, be able to be copied over to a web button when you paste.
Currently its hard for any of us to do this in a cross platform app that targets ios, web and desktop simply because the underlying items in the frameworks do not do this already.
And the IDE doesnt seem to sort things out right. Depending on what version of the IDE you use you might see in the example SameXPLATExplicitAPI that the Blue Canvas has its compat flags all off but thats really wrong since it SHOULD be compatible with desktop. It would be subclassed from the Desktop one. And using those modules on ios would be from the IOS one. And on web from the web one. But this doesnt work as I expect. In some versions they are all greyed out and things “run” but the paint events never get called 🙁
So trying to make a FramedCanvas, like above, that works in iOS, desktop, and web IS, at the moment, not possible.
Making it so things share as much of their API by DEFINITION rather than just by coincidence would make it so more code is, or can be, cross platform without needing to copy paste from project to project.
Imagine THAT world !
A lot of API 2 is extension methods that are replacements for the classic global framework methods.
String.LowerCase is for all intents and purposes the equivalent of Lowercase(string).
Except when its not.
If you happen to have methods that can return a wide variety of types you may not be able to use the extension methods.
For instance if you have something like
Function Foo(NameOfTypeToReturn as string) as Variant
// this code IS just for illustration purposes !
select case nameOfTypeToReturn
case "String"
return "string"
case "Double"
return 1.234
case "Integer"
return 99 // yeah that many red balloons !
else
return nil
end if
End Function
and you were to try and do
Dim s As String
s = Foo("Double").Lowercase
s = Lowercase(Foo("Double"))
only one of these will compile. It’s NOT the extension method style.
And it makes perfect sense why not.
An extension method has a specific signature.
Lowercase is defined like
Function Lowercase(extends str as string) as String
essentially for this to MATCH the parameter to it has to already BE a string. But the return value from Foo is a variant – that can be turned into a string – but isnt already a string. So that usage “doesnt match”. An dyou get a compilation error.
The second however will accept something that can be turned into a string. Which a variant can do. So it compiles just fine.