Released "ePubChecker", my first REAL Studio app.

As a full-blown app, ePubChecker makes a nice demonstration of REAL Studio 2010, with Window menu, About box, etc.

Validates any EPUB book file against the "epubcheck" Java library from Google/Adobe. This validation is handy for any such author, and is required by Apple for iBook submissions.

Unfortunately, I was only able to release on Mac OS X. I'm having technical difficulties with both the Windows and Linux versions. In Windows I appear to have a problem with pathnames in the file system; I should be able to resolve that easily. In Linux, the app immediately quits before any gui appears; not sure what I'm doing wrong there, and debugging has proven futile.

Update: The problem with my Windows edition was neither REALbasic nor my code. The problem was not even with Java which I call to run the "epubcheck" library from Google/Adobe. It turns out that the library itself does not like 8.3 short name paths, à la DOS.



Short name paths are what we get when calling "ShellPath" on a FolderItem in REALbasic in Windows OS. But when I fed that short name to the epubcheck library, the library reported no such file found. Switching to "AbsolutePath" in REALbasic made epubcheck happy. I suspect the I/O calls the Google/Adobe make are not 8.3 savvy. So for Mac OS X &Linux I call "ShellPath", but for Windows I call "AbsolutePath". Problem solved.

Lesson learned:

Test on all 4* platforms as I develop, rather than waiting to the end.

*REAL Studio 2010 Release 3 now deploys to four platforms: Mac OS X Carbon, Mac OS X Cocoa (still in beta), Windows, and Linux.

iDisk does not like files from FAT (DOS) disks

I often use the iDisk feature on my MobileMe account to move files between computers, to servers, etc.

Unfortunately, I encountered some frustrating errors recently when dragging files to my iDisk. Despite different files and folders, zipping, and even re-naming them, I repeatedly got errors saying the copy could not be completed as a file already existed with that name. Eventually I realized I was dragging directly from a thumb drive (flash memory device) rather than my hard disk. The thumb drive was formatted in Windows-compatible FAT format. Turns out that iDisk does not like copying from that format, at least on a Mac.

Workaround: I moved the items to my Mac's hard drive (in HFS+ format). Then copied to iDisk without a problem.


Generate a character in REALbasic

As of REAL Studio 2010, the best way to programmatically generate a character is by calling the method "Chr" on a TextEncoding. You may get a particular TextEncoding by name through Encodings. You pass the decimal number of the code point of the needed character.

There are various encodings, but the normal one within REALbasic is UTF-8.

Example, to generate the Tab character using code point 9:


To generate a bullet (•):


To generate an ankh (☥):


Beware of the built-in command "Chr" which you call directly in your code without any class prefix. That command is outmoded, and only works with the first 128 characters of ASCII. "Chr" fails with accented characters, bullets, or any of the million other Unicode characters. Make a habit of calling "Encodings.UTF8.Chr" instead.

Tip: For you Mac users, UnicodeChecker is a wonderful tool for looking up any Unicode character. This program is a nice GUI wrapper around a database of the Unicode characters. You can search by name such as "bullet". Free of cost.


Avoid EndOfLine at end of SQL with REAL Server 2009

Drove me nuts, but I discovered the cause of Error 21 "Not an Error" when using REAL Server 2009:
Adding a line terminator at the end of my SQL string.

This line does NOT trigger Error 21:
dim sql as String = "CREATE TABLE " + tableName + "( fld_text1 TEXT, " + EndOfLine + "fld_text2 TEXT);"

This line DOES trigger Error 21:
dim sql as String = "CREATE TABLE " + tableName + "( fld_text1 TEXT, " + EndOfLine + "fld_text2 TEXT);" + EndOfLine

It's that extra "+ EndOfLine" at the end that causes the problem.

I tried all 3 EndOfLine (Mac/CR, Win/CRLF, Unix/LF). Same behavior in all cases -- terminator on the end causes line 21.

Also, Error 21 is documented as "Library used incorrectly" but at runtime the Database.ErrorMessage is actually "Not an error".


Counting from Zero

A pal new to programming wrote me:
I'm reading that C programing book you bought me and I'm very annoyed by this counting starting at zero. Can you explain?

I remember annoying people in class counting one as zero.

I'm a little cranky this morning.

My reply…

Keep in mind that C is dumb. And old.
In the old days, computers had little memory. Computers were slow. Compilers were simple with limited capabilities. So, C was built to meet the needs of computers, not humans.

C counts from zero, typically for accessing arrays. The computer languages that survived over the decades tend to follow in the footsteps of C, to one degree or another. So many other languages count from zero.

The issue is:
  • Zero-based vs One-based
  • Index vs Ordinal
Imagine you are on your iPhone, standing on the corner of 1st and Main in Mukilteo, calling Bob to ask which house on the block is his house. He could say either:

  • Go to the 3rd house. (ordinal, by position in order)
  • Move your body forward, deeper into the block, by 2 more houses. (index, moving a cursor n number of units along a group)

    An array in all computer languages is a contiguous block of memory, a group of octets in most modern computers. Contiguous is the operative word. In C, the programmer accesses the data by telling the computer two things:

    (a) Tell where the beginning of the block of memory is located. The name of the array does that, instructing the computer to move its attention to a certain position in memory.

    (b) Tell how many octets to move forward from that starting point. If you want the first octet, you say "Move 0" because the computer is already at the first octet. If you want the second octet, you say "Move forward 1 unit" and that gets you to the 2nd octet.

    Say we have an array of 8 small numbers in an array named "myData". Say the array starts with octet # 4,054. This array uses octets numbered 4054-4061 as pictured above.

    Programmers usually think of that name "myData" as containing the array. But actually it doesn't contain the array; it just leads us *to* the array. That variable "myData" is just a single number (using 2 octets in this example, # 2,011 & 2,012), the number of the memory location where the array begins. It leads us to the first bit of the first octet of our array. Note that the arrow above points to the front of the first octet, not the contents inside.

    Begins is another operative word. If we have the beginning of a contiguous group, then we can bounce to and fro, reaching any item in the group. We just need to know how many jumps to make. If you want the first item, you make no jumps (index = 0). If you want the 3rd item, you make two jumps (index = 2).

    Think of each octet as the houses on Bob's block. If you are standing at the corner, you are already at the first house. If Bob lives in that first house, you don't have to walk further, that is, no jumps required (index = 0). If Bob lives at the 3rd house, you need 2 jumps (index = 2).

    What makes arrays fast and simple for the computer is this jumping around, jumping x number of octets forward or backward to access data without any other tracking, considerations, or overhead. 

    If we access by an index number (zero-based counting), we are asking to move our attention/cursor/marker inwards so many units into a group. If we access by an ordinal number (one-based counting), we are asking for a particular position within that group.

    Do data groups have to be zero-based? No.

    In modern computing languages, such as REALbasic, Java, and Cocoa, we have other data structures besides arrays, sometimes known as "Collections". Collections are typically ordinal, one-based. These other structures take more memory and run slower. But today's computers can afford that. Collections are much easier on human brains so they make programmers more productive while writing better code though requiring more work from the computer.


    Cheat sheet of flow control in REALbasic

    As of REAL Studio 2010, here's a quick list of the flow control keywords in REALbasic language.

    Loops (where 'boolean' means some expression that resolves to Boolean value):

    • While boolean … Wend   (test at top of loop)
    • Do … Loop Until boolean    (test at bottom of loop)
    • For someVar = 0 To limit … Next   (regular FOR loop)
    • For someVar As Integer = 0 To limit … Next   (declaring data type of counter in FOR loop)
    • For Each elementVar As arrayType In array … Next   (for looping an array)


    Current Method Name in REALbasic

    To get the name of a method executing at runtime, call this not-so-surprising command:

    This is handy for reporting and logging errors, as well as debugging. For example:

    MsgBox "Something has gone wrong in method: " + CurrentMethodName

    Causing a compiler error -- on purpose! (in REALbasic)

    If you have some broken code you want to get back to soon, you can cause a compiler error to happen as a reminder.

    Add this simple line:


    The line above is good for a quick problem you expect to resolve ASAP, but you're afraid you might get distracted.

    If the problem is going to be around for a while, you may want a message to appear as part of the compiling process. To do so, type :

    #pragma error "not yet implemented (or any message you want here)"

    Likewise you can cause compiler warnings. Your app will compile, but your message will appear in the list of warning messages.

    #pragma warning "your message goes here"

    REAL Studio 2010 has some other pragma tricks too. Several involve shutting off safety features at runtime to gain more speed.

    "ListBoxEnhanced" class adds row coloring & ColumnTag

    I am sharing a REALbasic class I wrote, "ListBoxEnhanced", that adds  2 features to ListBox:

    • Alternate row coloring
    • ColumnTag
    The row coloring works automatically. Just drag "ListBoxEnhanced" to your Window rather than ListBox. For existing ListBoxes on your forms, just change their "Super" property popup from "ListBox" to "ListBoxEnhanced".

    To attach an object or value to a column, call the ColumnTag getter/setter methods.

    For more info and downloads, see the "ListBoxEnhanced" section of this page.

    Note that REAL Software has implemented ColumnTag for a future release, after REAL Studio 2010 Release 3.


    "Menlo" - The new monospaced font in Mac OS X

    For those programmers using "Snow Leopard" (Mac OS X 10.6), check out the new font bundled by Apple. Menlo is its name, and as a monospaced font it works well for programmers. I suggest changing the default monospaced font in various apps to Menlo, such as TextEdit, other text editors such as TextMate and JEdit, as well as your web browsers, email client, and Terminal programs such as Path Finder.

    Menlo & DejaVu fonts overlay
    Menlo is based on the monospaced member of the Bitstream Vera font family. While the Vera font had a limited set of glyphs, another open-source project based on Vera was launched to improve and expand that set. DejaVu is free of cost and under active development with volunteers around the world contributing glyphs for all sorts of languages. Linux distros are commonly including DejaVu and even making it their default system font. If your are using older versions of Mac OS X, or Windows, I suggest downloading DejaVu to use its monospaced member for your programming work. Read more about the overlay image above.

    Pragmata font demo
    While Menlo and DejaVu (and Consolas) are runner-ups, the all-time best programmer's font is Pragmata sold by its Italian creator as well as Fonts.com and FontShop. Whereas monospaced fonts typically go wide to increase readability, Pragmata goes tall. Costs money, but for those of us staring at source code for hours at a time, it is money well spent.

    Tip: Take this with a grain of salt as I have not tried it, but Mac customers who also use Windows may be better off buying the Windows version of the Pragmata. I have heard that Mac OS X can read the Windows format of such fonts, but not vice-versa.