realbasic gems
Software without bugs #2
realbasic gemsEarlier, I challenged everyone to write a bug-free program that appears to be trivial. All it has to do is raise one number to an arbitrary power and display the results. However, bug-free is a very difficult thing to achieve, as anyone with experience in software can agree to. Here's a set of of the most common bugs that this particular project suffers from: 1) Since it's meant to provide *arbitrary* exponents, you cannot assume that an Integer input is sufficient. What if the user really wanted to do a square root by passing in .5? So you need accept floating point arguements as well as return a floating point result.
Software without bugs #2
realbasic gemsEarlier, I challenged everyone to write a bug-free program that appears to be trivial. All it has to do is raise one number to an arbitrary power and display the results. However, bug-free is a very difficult thing to achieve, as anyone with experience in software can agree to.
Here's a set of of the most common bugs that this particular project suffers from:
1) Since it's meant to provide *arbitrary* exponents, you cannot assume that an Integer input is sufficient. What if the user really wanted to do a square root by passing in .5? So you need accept floating point arguements as well as return a floating point result.
Challenge: software without bugs
realbasic gemsHere's a fun little challenge I came up with while on my flight back to California: create a simple application that is bug free. This is a demonstration of the fact that "bug free" is a very difficult thing to achieve, if not out-right impossible. I came up with this challenge because I was reading yet another diatribe on the forums from some users who don't seem to reside in the same world as the rest of us. ;-) So here's the challenge: you are to write an application which calculates arbitrary exponents in pure REALbasic code.
Challenge: software without bugs
realbasic gemsHere's a fun little challenge I came up with while on my flight back to California: create a simple application that is bug free. This is a demonstration of the fact that "bug free" is a very difficult thing to achieve, if not out-right impossible. I came up with this challenge because I was reading yet another diatribe on the forums from some users who don't seem to reside in the same world as the rest of us. ;-)
So here's the challenge: you are to write an application which calculates arbitrary exponents in pure REALbasic code. It should accept two inputs, and display the output. I don't care how you accept input (EditField, StdIn, etc) or display output (MsgBox, StdOut, etc). We will assume that any form of input and output are considered out of the scope of the challenge. The calculation algorithm should be purely of your own creation (you can't cop out and use the Pow function in REALbasic, or a declare, plugin, etc).
Forward referencing
realbasic gemsWhat should the following REALbasic code do:
#if Foobar
Const Foobar = false
MsgBox "Foobar!"
#endifIf forward referencing is allowed, then this code should not exist in the resulting application (though it should compile). If forward referencing is not allowed, then this code should fail to compile entirely.
So if you're in the camp of people that claim the above code should fail to compile, then you've also placed yourselve in the camp that claims this code should fail to compile as well:
Sub SomeMethod( test as Integer = kSomeConstant )
Without ubiquitous forward referencing, this code may or may not compile, depending on how your project is rendered out. Since you have no control over the order items are rendered, you cannot assume that constants have been rendered before methods in any given class. And it's not just limited to code items within a class -- what if kSomeConstant is a global constant that lives in a different module? You can't be assured that the module has been compiled before the method in another class.
Computed Properties + Array return types = ???
realbasic gemsWhile browsing around in the feedback system the other day, I ran across a feature request that caught my eye. It was asking for the ability to use arrays as the return type for computed properties. Once upon a time, I thought "hey, I really want that too!", but that was a long time ago. So I spent some time thinking about what it would actually mean to allow arrays as return types for computed properties, and I realized "ooh, that's not a good idea!" because of the aliasing problem.
Imagine, if you will, some code that looks like this:
someClass.someComputedProperty.Append( someItem )
Well, since the array is computed, that means that someItem is being appended to an array that will be immediately destroyed after the call ends because nothing else is holding a reference to it. Could you tell that from looking at the code? Probably not!
Plugins Can Be Fun (Part Two: g++)
realbasic gemsLast time, we covered the basics behind what a REALbasic plugin was, and how they worked -- so if you didn't read that posting, you will want to go read it now. We put that knowledge to use with Microsoft Visual Studio 2005 and built the most basic plugin possible for Windows.
Today we're going to take our knowledge and apply it to g++ (a variation of gcc, really) on Linux for building a shared library object to act as our REALbasic plugin. At the end of the post, we'll have made the same empty shell that we did last time.
Win32 Plugin SDK unlikely gotcha
realbasic gemsSo I just stumbled across a very unlikely, but still possible, thing to watch out for when making plugins for REALbasic. On Windows, some compilers (like Visual Studio) support special functionality for thread local storage. Instead of requiring you to use the Tls APIs, Visual Studio exposes a special __declspec for TLS:
__declspec( thread ) int someVar;
This would declare a 4-byte piece of thread local storage (so each thread would get its own copy of someVar, even though it's global in scope).
REALbasic plugins cannot make use of this because it takes special magic from the system loader to make it work. The REALbasic plugin loader doesn't do the necessary fiddling with the TEB to make this magic work, and I highly doubt it ever will (just due to the fragility of it alone). If you really need thread local storage, use the Tls APIs provided by Microsoft like TlsAlloc, et al. However, TLS is so rarely used that 99% of plugin devs out there can simply ignore this gotcha.
Plugins Can Be Fun (Part One: Visual Studio 2005)
realbasic gemsEveryone knows that there is nothing more enjoyable than writing plugins, right? I know I certainly enjoy it, depending on the day, how the planets line up, how much I've had to drink and what I need to accomplish. ;-) But seriously, writing plugins for REALbasic isn't nearly as hard as a lot of people make it out to be. The API documentation is lacking (to say the least), but that has been rectified for the next SDK release. The "how to get started", however, has not been updated in ages, and you can assume it's all lies, lies and more lies. Not because it's wrong, mind you -- but because it's old and refers to ancient development environments which no one uses anymore. Pascal with MPW? Uh... CodeWarrior? VS 6? Yeah, like I said, it's out-dated, to be sure. Hopefully that issue will be addressed in a future release as well (but I can assure you it won't be addressed in the next release, unfortunately).
Items of RegistryItem Interest
realbasic gemsI learned of two rather interesting RegistryItem factoids while playing around tonight that I thought I'd share with others. One appears to be an oversight with the API and a way around it, while the other appears to be a mysterious bug that took a while to track down (and a way around it as well).
First, the oversight. It appears that there is no way to get the name of a *folder* for a given registry item -- you can only get the names of *keys*. This can be rather problematic if you're attempting to search both names and values of everything in the registry. The RegistryItem.Name API only gives you access to key names (for key/value pairs). To get around this, you can make use of the RegistryItem.Item method to get the folder by index, and the Path property to figure out the folder's name. The code would look something like this:
Function FolderName( extends r as RegistryItem, index as Integer ) as String
dim child as RegistryItem = r.Item( index )
dim parts() as String = Split( child.Path, "\" )
return parts( UBound( parts ) )
End Function
This code obviously needs some error checking, commenting and what-not, but you get the idea. Find the child item by index, get its path, and return the last part of the path -- that'll give you the folder's name. A bit inefficient, but certainly functional in a pinch.

