Archive for August, 2005

August 30th 2005

Using Class Interfaces for Fun Scoping

I’m about to reveal to you a very cool feature that not many people know about. Or perhaps I’m fooling myself, and it’s known, but I didn’t realize it. Let me just dive right in with an example:

Interface TimerCallback
Sub TimerAction( t As Timer )
End Interface

Class Foo
Implements TimerCallback
Private Sub TimerAction( t As Timer )
MsgBox "I got called!"
End Sub
End Class

Now, something subtle just happened. What was it? I just implemented an interface using a private method.

(dramatic pause)

What does that mean exactly? Well, it means that you can implement an interface with any scoping you’d like to. This provides some great possibilities. The most obvious being that since you can do this, people can’t see TimerAction in autocomplete for Foo, nor can they access it without casting to a TimerCallback first. This allows you to specify your public interface for a class, without resorting to undocumented hacks (which I will leave undocumented here too :)).

So, let’s flesh out the above example. We have this class that will now throw up a message when this method gets called. Let’s create a timer that talks to things through the TimerCallback Interface.

Class CallbackTimer
Private mDelegate As TimerCallback
Sub Constructor( deleg As TimerCallback )
mDelegate = deleg
End Sub
Sub Action Handles Event
mDelegate.TimerAction( Self )
End Sub
End Class

Now, when you create a CallbackTimer, you pass in the instance of Foo, and it can call the TimerAction method. However, without having to typecast elsewhere, no one else can call this method.

This feature can be used to design some cool mechanisms for communication amongst classes. If you’ve used this, let me know what cool things you’ve come up with!

1 Comment »

August 25th 2005

The Visitor Design Pattern

Since Aaron’s on vacation, and someone asked about this on the NUG, I decided a nice color-syntaxed response would be good :)

So, what’s the visitor pattern? To quote WikiPedia: “In software engineering, the visitor design pattern is a way of separating an algorithm from an object structure.” What is this good for? Well, essentially, it allows you to extend your classes with new functionality, without actually modifying the classes. It allows you to group related tasks into one class, and it deals with the unmodified classes. I’m going to steal WikiPedia’s example:

Interface Visitor
Sub Visit( wheel As Wheel )
Sub Visit( engine As Engine )
Sub Visit( body As Body )
Sub Visit( car As Car )
End Interface

Class Wheel
Name As String
Sub Accept( visitor As Visitor )
visitor.Visit( Self )
End Sub
Sub Constructor( wheelName )
name = wheelName
End Sub
End Class

Class Engine
Sub Accept( visitor As Visitor )
visitor.Visit( Self )
End Sub
End Class

Class Body
Sub Accept( visitor As Visitor )
visitor.Visit( Self )
End Sub
End Class

Class Car
Private engine As Engine
Private body As Body
Private wheels() As Wheel

Sub Accept( visitor As Visitor )
visitor.Visit( Self )
engine.Accept( visitor )
body.Accept( visitor )
For i As Integer = 0 To ubound( wheels )
wheels(i).Accept( visitor )
Next
End Sub

Sub Constructor()
wheels.Append New Wheel( "front left" )
wheels.Append New Wheel( "front right" )
wheels.Append New Wheel( "back left" )
wheels.Append New Wheel( "back right" )
engine = New Engine
body = New Body
End Sub
End Class

Class PrintVisitor
Implements Visitor
Sub Visit( wheel As Wheel )
MsgBox "Visiting " + wheel.Name + " name."
End Sub
Sub Visit( engine As Engine )
MsgBox "Visiting engine."
End Sub
Sub Visit( body As Body )
MsgBox "Visiting body."
End Sub
Sub Visit( car As Car )
MsgBox "Visiting car."
End Sub
End Class

Dim car As New Car
Dim visitor As New PrintVistor
car.Accept( visitor )

Whew, ok, that was a mouthful. So, what does this get us? Well, if you were to create a project with this, you’d see the messages, “Visiting Car”, “Visiting front left wheel”, “Visiting front right wheel”, “Visiting back left wheel”, “Visiting back right wheel”, “Visiting body”, and “Visiting engine.” This example isn’t a very useful one, because it only shows one visitor. The power of the visitor pattern shines through when you are able to implement multiple visitors.

Take for example, this visitor for the above example:

Class WheelFinder
Implements Visitor
WheelToFind As String
FoundWheel As Wheel
Sub Visit( wheel As Wheel )
If wheel.Name = wheelToFind Then
FoundWheel = wheel
End If
End Sub
Sub Visit( engine As Engine )
// This method has been intentionally left blank
End Sub
Sub Visit( body As Body )
// This method has been intentionally left blank
End Sub
Sub Visit( car As Car )
// This method has been intentionally left blank
End Sub
End Class

Now, we have two solutions implemented without ever changing the implementation of the original classes. If we need to find the front-left wheel of a car, we can simply say:

Dim finder As New WheelFinder
finder.WheelToFind = "front left"
myCar.Accept( finder )
If finder.WheelFound <> Nil Then
// do something to the wheel
End If

While these classes are very simple, the possibilities are much larger when dealing with more complex data sets. If you’re faced with needing to loop over your data structure looking for something that matches some criteria, the visitor pattern will help. Not only that, but if you find yourself needing to do it in more than one case with different criteria each time, it will help out drastically. Once you’re utilizing the Visitor pattern, if you modify your structures to include a new class or new property, you’ll only need to update the Accept methods, and all your visitors will be ready to accept the new structures. Compared with needing to update a lot of custom loops, it’s a much more favorable approach.

4 Comments »

August 21st 2005

Scoping Decomplexified

Alright, yes, I realize that “complexify” isn’t a word… yet. However, I find it simpler to say “complexifies Foo” rather than saying “makes Foo more complex”. So, I insist on its usage, so that it will be widely adopted, and the etymology will attribute me as the first who uttered it.

But anyways, onto scoping, and how to understand it better. I’m going to draw on an analogy throughout this post. The analogy is my family. Since a common word we use is “inheritance” when dealing with scoping, I think it fits quite nicely. So, here’s a nice diagram of part of my family.


Click here for the full sized image

And it’s related declarations:

Class Mom
Protected Equinox As Vehicle
End Class

Class Jon
Inherits Mom
Private MacMini As Computer
End Class

Class Justin
Inherits Mom
Private Dell As Computer
Protected TV As PlasmaTV
End Class

Class Jordyn
Inherits Justin
Private Lego As LegoGuy
End Class

Class JW
Inherits Justin
Private Lemon As TartyFruit
End Class

Class Bob
Public Bus As Vehicle
End Class

Ok, so now to the explanations. There are three scopes that you can use inside of a class:

  • Public: Public is the least restrictive of all. Anything declared as public can always be accessed anywhere.
  • Protected: Protected is quite a bit more restrictive. Anything declared as protected can only be accessed within the class it’s declared in, or any subclasses of the class it’s declared in. (Don’t worry, we’ll get to the examples soon!)
  • Private: Private is the most restrictive. Anything declared as private can only be accessed within the class it is declared in.

Once you get the hang of these terms, they will feel more familiar. So, let’s look at a few things on the chart to help familiarize ourselves with the terms. If an item sitting next to a person (a [piece of] property) is highlighted in Red, it is Private. If it’s highlighted in Yellow, it’s Protected. If it’s not highlighted, it’s Public.

Let’s start with my Mom, at the top of the chart. She has an Equinox, and provided we’re in Alaska, I’m allowed to drive it, as is my brother. Thus, it’s protected, because she allows us to drive it. Technically, Jordyn and JW could drive it because they inherit from my Mom, but they know better than to try that!

Next, let’s take a look at me (Jon). I have a Mac Mini (which is what I’m writing this on right now). It’s private, because I don’t like people messing with my machines I use for programming :) This means that no one else on the entire chart can access it.

Moving over to the right is my older brother Justin. He has a Dell, and like me, he doesn’t want anyone else using it, so it’s [a] private property. However, he also has a nice new flat-panel TV he just bought, and it’s protected, because he lets Jordyn and JW watch Baby Einstein on it as well. (If you’re asking yourself, “what about Jon or Mom?” just wait a minute :))

Finally, Jordyn has some legos that she enjoys playing with, but she’ll get really mad if you try to take them away, so she keeps them private. JW, on the other hand, has his own slice of lemon (he really likes those, oddly enough). Honestly, who wants to have a lemon after a baby’s been gnawing on it? Let’s keep it private :)

Lastly, Bob. Bob is just an anonymous person outside of the family. While it’s fair to say we most likely all share some sort of inheritance path in real life, let’s not think about that for now and only consider the chart ;) Bob drives one of Austin’s public busses. Since he lets anyone on it, it’s public. That means that, if we wanted to, Mom, Justin, Jordyn, JW, and I could use the bus.

So, for the more general way of analyzing the chart, let’s consider it this way:

  • Any [piece of] property that is highlighted in red can only be used by whoever owns it. (Private property)
  • Any [piece of] property that is highlighted in yellow can be used by whoever owns it, and the children of that person. (Protected property)
  • Any [piece of] property that is not highlighted in any color can be used by anyone at all. (Public property)

Hopefully that has cleared up what scoping within classes is like. However, there are two more issues to talk about.

Providing access outside of the chain
Ok, so while I don’t like anybody just using my Mac Mini, I do occasionally let people use it. I give them special access. In REALbasic, I would define myself as:

Class Jon
Inherits Mom
Private MacMini As Computer
Public Function CanIUseTheComputer( who As Person ) As MacMini
// returns nil if access is denied
End Function
End Class

In this example, I declare a private property MacMini as Computer. I then can restrict access to anyone I choose with my public method (that anyone can call). It allows me to control my Mac Mini, but at the same time not be a jerk.

Similarly, my brother allows both my Mom and I to watch his nice TV, but we have to be invited over first. I can’t just barge in and watch TV at 3:00 AM, so he provides a Public accessor as well.

The rule of thumb is to provide access to only those who you think need it all the time, and provide an accessor for the ones that you want to control. You can even do something like provide a Protected function that accesses a Private property so that some subclasses can call that function to gain access to the data.

Modules and Scope
Modules are slightly different. Because modules can’t inherit from other modules, a Protected scope doesn’t make sense. However, since data in a module doesn’t belong to any particular instance of some object, one more scope is available. Here’s the scopes and how they work:

  • Global: Global items are available anywhere, and don’t need any prefix to access them. If you declare a property “Foo as Integer” to be global, you can use “foo” anywhere in your code. Optionally, you can use the dot notation to access the item like ModuleName.foo
  • Public: Public items are still available anywhere, just as they are in classes. You just have to use the dot notation to access them. So, if you declare “Foo as Integer” to be global, you would have to use MoudleName.foo to access it. This doesn’t do anything at all to prevent people from using it — it just makes the global namespace cleaner by requiring you to use the module’s name when accessing it.
  • Private: Just like in classes, private items are only available to whatever declares them. So, if you declare “Foo as Integer” to be private, Foo can only be accessed within the module it was declared in.

This concludes the decomplexification of scope. If you have any questions, feel free to leave them in the comments. I’ll revise/add/remove as needed.

Up next: Using Class Interfaces for Fun Scoping

4 Comments »

August 3rd 2005

REALbasic 2005r2

Well, REALbasic 2005 release 2 has shipped as of yesterday. While the last couple weeks have lead to very few things done by me (over a week of vacationing, an educational day, and several days at ADHOC), I still had some good stuff in there, and enjoy what everyone else accomplished for this release.

It’s no secret that this release contained a lot of bug fixes and usability fixes. However, those aren’t interesting to write about here, so we’ll just say that there’s 119 fixes in this release.

However, there’s also some great features. Here’s my favorites:

Array.SortWith. This is a beautiful function. Let’s say you have an array of Names and IP addresses, and you wanted to sort both arrays by the name. Previously, you’d have to write your own sort algorithm. Now, you can just do this:

Names.SortWith IPAddresses

Much easier, much cleaner. On top of that, the SortWith function takes a ParamArray, meaning you can pass in as many arrays as necessary. If the size of the arrays differ, you will get an OutOfBoundsException.

Viewing arrays in the debugger. When doing this with arrays of objects, you will see a popup menu. This popup menu has a list of properties of each of the objects. You can select which property you want to see, and you can instantly see the property values for each object in the array. It’s a real timesaver.

Computed Properties: Finally, a true property without having to create a getter and setter method. Why is this good? Well, a couple of reasons — they are viewable in the debugger and they are grouped and easily distinguishable.

Properties can have default values: You can now specify a constant as a default value for a property. Better yet, this value is used when putting an instance of this class on a window.

Target constants: TargetBigEndian and TargetLittleEndian. It only took me a few minutes to add these constants, but you should be using them. In time, when we support Intel Macs, you will not be able to assume that if you’re on the Mac, you should be Big endian. So, if you’re doing anything with MemoryBlocks, remember to use the LittleEndian property, or if you need to do manipulations yourself, check TargetBigEndian and TargetLittleEndian for those types of things.

Tabs now truncate instead of overlap, and remember the order of tabs. This was something that caught me a lot in release 1. I would edit code on tab 2, run the project, finish debugging, and end up on tab 5 instead. There was an expectance that before and after running, the same tab would be active, unless you switched tabs while running. After discussing it internally, we decided it was best to just make the tabs have an order of front to back, and activating it brought it to the back. We also decided that browsers such as Safari and FireFox should steal this behavior from us.

In addition, instead of overlapping and potentially obscuring the close box, the tabs now truncate when drawing. It affects the largest tabs first, and works pretty well. I find it much more usable than the previous system.

Finally, array autocomplete works very well. In fact, I’ve found it to be better than in 5.5 in all cases I can find.

Well, that about wraps it up for the wonderful things I have been dying to write about for the last few weeks. Can’t wait to show you r3! :)

3 Comments »

August 1st 2005

A look back on ADHOC 20

Well, ADHOC 2005 went really really great. I got back yesterday, but I participated in the more traditional sense of ADHOC/MacHack tradition by only logging in about 16 hours of sleep between Thursday and Sunday.

I arrived in Dearborne*, just slightly outside of Detroit, on Wednesday evening about 8:00. I checked into the hotel, set up my Mac Mini in my room, and registered for the conference. I found Michael Dautermann, the guy in charge of PR this year, and coincidentally he hadn’t eaten yet either. While waiting to head out to find something to eat, I talked with a couple of people from Metrowerks (also an Austin company), nothing too serious, just being friendly. At one point, one of them asked, “Are you hiring?”… More on why someone would ask that in a bit.

Michael and I went out, and he had a middle-eastern restaurant in mind (he’s originally from the area), and I had to concur, it was excellent food for under $10 a plate. After dinner, there was only a little bit of time before we found out that there was pizza that evening, also. Oops! :) The pizza that ADHOC gets is always great. I don’t even know which restaurant it comes from, but it’s a deep-dish style, rectangular pizza that is just absolutely delightful. I had a couple squares as we headed in to listen to Jordan Hubbard talk.

Jordan is the co-founder of the FreeBSD project. He also developed large parts of the basis of the FreeBSDPorts project. After 10.0 developer preview 4 came out, Jordan bought a Mac and loved it. In response to this, the audience was in shock. How could someone love a pre-release version of OS X? Simple: he loves UNIX, and even at 10.0dp4, he could tell that it was one of the better done GUIs atop of UNIX before.

Jordan was very entertaining. For some great quotes, check out Avi Drissman’s blog entry. I had the pleasure of talking with Jordan later in the conference, as he hunted me down to help him install Quesa to check out RB3D. Since it sounded like he was just wanting to mess around with 3D, didn’t have any models or such, I also pointed him to Asher Dunn’s OpenGL library.

In fact, one of the great things about handing out free REALbasic licenses was that instead of feeling sheepish about bringing REALbasic up in conversations that were centered around other products, I felt just fine because everyone could try it free of charge. I was sought out this year to help people, answer questions, and more.

Anyways, back to the keynote. It ended at about 2:00 AM in traditional MacHack/ADHOC fashion. However, Jordan then started the Q&A portion, which drilled from everything about DarwinPorts and security to HyperCard. Yes… HyperCard. People were getting a little emotional for 3:00 in the morning, giving Jordan and Keith Stattenfield (another Apple engineer, who was sitting in the front row at the time) an incredibly hard time for not open-sourcing HyperCard. They did a great job not being too defensive about the fact that it wasn’t them that made that decision. But, in reality, a good point was made that Jordan agreed to: when end-of-lifing a product from this point on, there should be an effort made to determine if the project is a good candidate for opensourcing.

At around 3:30 in the morning, I called it a night.

I was up at 9:00, preparing slides for my afternoon talk about the Intel switch. I had spent several days constructing my slides before the conference, but for some reason they weren’t opening up anymore. I still had my outline, thankfully, so I spent several hours reconstructing the slides. I went downstairs, did some scheduling updates (which included postponing my second Intel session), and had lunch. I sat at the table with Keith Stattenfield, Andy Ihnatko, and Scott Knaster. While the conversation focused a lot on comic books, it’s fun to see these guys get together. They’re just hilarious!

I had to withdraw from the table early, unfortunately, to go set up my Mac Mini for my “Supporting Intel Macs: the easy stuff” session. A lot of people showed up, and I felt it went really well. I know several people enjoyed it, as in passing several times I was told, “Great session.”

The rest of the afternoon I spent socializing and programming. During the course of the evening, I answered questions about REALbasic, pondered what my showcase entry would be, and pondered if and when I should recreate slides for my “Supporting Intel Macs: the nitty-gritty stuff” session. I had covered a lot more than I had expected in the easy stuff session, so I didn’t know if slides would be as beneficial as an interactive code-as-we-go session.

At 11:30′ish, more pizza was delivered. Good stuff as usual, and we wandered in to hear Andy Ihnatko’s speech. I’ve never heard him speak except at the table earlier that day, but it was downright hilarious. The keynote lasted until about 2:30ish, but the Q&A (in this case, general bantering between audience and Andy) lasted much longer, with me giving up on hearing the last of it at around 4:00 am, since I had to give another session in 6 hours.

One thing that was pretty cool was that Andy answered a question by drawing a connection to REALbasic. He loved the product when he was able to rewrite his blogging software in it, decide to try it on Windows by clicking a box, and have it work straight away. It’s always fun to see the product you work on every day being mentioned all over the place.

After getting back to my room at 4:00 am, I decided perhaps a great session idea would be to write a fractal generator that loaded and stored information to files, and then optimize it for Altivec and then SSE2. At 5:30, I decided that project was a bit more ambitious than I’d wanted to do, and Intel’s download site for their SSE2 guide wasn’t working properly for me. So, my eyelids won the war of sleep for a few hours.

At about 9:00, I was back up again, and rethought what I should do. I decided I would go forth with an example that involved reading and writing files, doing some number crunching on pointers, and a few other practices that would exhibit some gotchas in different ways. At 9:50, I was downstairs with my Mac Mini, Linux Laptop, and various accessories to find that my room wasn’t set up yet, and there were really only 5 or so people in the atrium (which was understandable due to the late keynote). I finally found someone to unlock the door that had the projectors, set it up, grabbed a bagel, and presented to a whopping 10 people to start with. More people wandered in, but I deviated from my plan. Since the audience was small enough, I simply opened it up to Q&A. I knew some of the people in there, and others had already asked me a few questions the night before, so I had a good idea that most of them weren’t worried about much. So, the people that had remaining questions were able to get them out, and I think it definitely benefited those people. Plus, due to starting late, it was nice to have my session end on time.

I stayed in that room and watched an excellent presentation on Dashboard and the HTML/CSS extensions to go with it. Very informative, and it was something I hadn’t had time to learn about yet. Now I have.

I ate lunch, and after lunch attended a session about OpenGL on the Mac. I knew a lot of the material, but I did learn a bit, and I also made a great contact. The presenter was a former employee of SGI, has worked with OpenGL for a long time, and is working on a book due out later this year about OpenGL on the Mac. He and I later sat down to try to hack the Mac OS X window server, but we unfortunately ran out of time before we figured out how to inject ourselves into the rendering phase for the display. We agreed to figure it out next year, and he parted his ways to go to SIGGRAPH.

So, there I was, 6:30 PM, 5 and a half hours to the showcase, and no idea what to do. Finally, Brian Geiger invited me to hack together an idea that Andy I. presented in his keynote. Having no better ideas, I did it. I’ll explain more on it in a future post, once I can get a screenshot and everything.

We completed the entire hack, involving a dylib, injector for that dylib (based on Mach_*), Applescripts to gather information, and a REALbasic application to display information.

The showcase went well, and there were some great entries. I don’t really care to describe them all, hoping that someone else will :) Ours demoed pretty well, and I thought it was quite exceptional for less than 5 hours working on it.

Saturday was filled with more great sessions, and in the afternoon, I presented my session, “Write a Cross-Platform Game in Two Hours.” I wrote most of it in two hours, but lacked a few finishing touches to tie all the components together. So, with about 20 minutes left, I opened up the existing project, showed them the parts, explained them, then invited an attendee to play against me. We ended just a few minutes before the awards banquet.

The awards banquet had some good food, good stories at the table, and an entertaining awards ceremony. Our hack didn’t win any special prizes, but we did get a towel with ADHOC 2005 embroidered on it (the theme was Don’t Panic, which was from the Hitchhiker’s Guide to the Galaxy — the connection is there for people who have read the book).

Afterwards, I helped Jordan get his 3D working, and then we drove to the movie theatre to watch the annual bad movie. This year’s was Stealth. Surprisingly, it wasn’t as bad as I thought. However, that’s not to say it was good. We were laughing so much during the “serious” parts of the movie, that at one point a local yelled, “Shut the hell up, you crazies!” That didn’t really stop the majority of the group.

After we got back to the hotel, we had the traditional ice cream social, and then gathered around Keith Stattenfield to hear “Keith Explains!” Unfortunately, I can’t link to information about his local TV show, because it seems to be showing the default Mac OS X server web page (Update: He has fixed his webpage. You can view it at http://www.keithexplains.com/). However, I can assure you that listening to him and other ADHOC’ers pick apart a movie is quite entertaining. This year, it consisted of:

Keith Stattenfield- Giving original insights, stepping through the movie
Adam Engst: Chiming in when we have wandered off on a side topic for a few minutes too long.
Everyone else: Discussing with Keith about meaning behind the movie, or noting other oversights in the story/science/technology of the movie. Also, quickly moving said discussions into slightly related territory, over and over, until we almost forget where we were in the movie.

This movie was so bad that after nearly 4 hours of explaining it, we had only gotten about a third of the way through. Yes, there were that many strange or unexplainable events in the movie I finally called it an evening, and bid adieu to everyone.

I slept for about 4 hours, and started packing my bags. I was down in the lobby at about 9:30, checking out, and hoping to catch a ride to the airport. I succeeded when Scott Ribe pulled around the front of the building in his rental car. Scott, if you read this, thanks :)

Back in Austin, I fell asleep, woke up and talked to friends online, and then fell asleep again. I still have more to catch up on. All in all, it was a fun and very worthwhile experience for me, as I learned things, met great people, and extended friendships with those I had already met.

* It was discovered that technically the Holiday Inn is in Detroit, but only by 1/4 of a mile or so.

6 Comments »