If you don’t have it, you’re in trouble…

I bumped into a friend of mine on the way into work this morning. I’d heard that she’d recently started a new job (really, I’m a Facebook stalker…much easier to keep up with friends like that - no need to actually have a conversation…), and I was curious how it was going. Her reply (paraphrased):

“It’s been a switch moving to an [Advertising] agency. They don’t even have source control! And I only have one monitor - it’s killing my productivity!”
Name withheld to protect the innocent…

Let that be a lesson to you.

Really, if you aren’t using some form of source control, you’re in trouble. And do not make the mistake of confusing source control with backup: the intent of backup is to ensure that you always have a certain entity, be it a file, a set of files, perhaps an (il)legally downloaded music collection. Source control isn’t concerned with the whole, final product; its intent is to capture change. Hopefully, as a developer or designer or hybrid, you see the value in that. If not, if you haven’t been bitten by this particular dog, I’d recommend you start using source control and avoid it entirely.

You see, developing a product, be it a website, mashup, game, desktop app, what-evah, is an iterative process. You go from A to B to C to D. You’re always in flux, always moving, incorporating new ideas, recalibrating, learning and relearning. And one day you’re going to break something that worked fine yesterday. Or have a client tell you they liked it the old way. Hell, you might like it the old way yourself! And then, boom - your ever-overwriting backup strategy goes to hell. You’re stuck going back to figure out what the hell you did to have it work the way it did before. With source control, you can simply roll back or merge the old with the new (well, hopefully simply…).

Now stop being selfish and thinking only about yourself. Most of us don’t live or work in a vacuum, after all. You’ve got multiple people working on the same set of files. To quote the Big Bang Theory, “I believe the appropriate metaphor here involves a river of excrement and a Native American water vessel with out any means of propulsion.” Overwriting other team member’s changes, losing your own changes, it’s a nightmare.

Really. I’ve been there.

So do yourself a favour: set yourself up with source control. First day at the new job, and they don’t have it? Set it up. Quit if they don’t let you. What to use? Lucky for you, you’ve got lots of choices. Microsoft shop? Use VSS. (Ok, that’s a joke…if you can afford it, and really have the need, pick up Team System.) Set your team up with SVN (and, if you’re on Windows, grab Tortoise - you’ll thank me). Find a plugin for your IDE of choice (you do use an IDE, right? sadly, there’s no SVN plugin for FlashDevelop that I know of - yet - but working with Tortoise makes it relatively easy). Go to town. Don’t have your own server or infrastructure to install on? Use unfuddled.com - an excellent project management and collaboration tool that includes both SVN and GIT, along with a suite of other tools for you and your team.

So there you have it. Many have said it more eloquently before me, and many more will say it better (Jeff Atwood of StackOverflow.com fame, for one). But if you’re reading this, forget about how horrific my prose is this evening and get yourself some source control.

(Don’t even get me started about how bad email is for communication…set yourself up on a collaboration platform and get the important crap out of your inbox…)

(Ok, I really think I’ve put off doing my timesheets long enough…bags…)

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

When Copywriters Try To Program

Axe Geeky AdNot that I'm against a bit of cross-pollination, and I certainly enjoy the occasional ad that speaks to my inner (and outer) geek, but if you're going to do it, do it right. Case in point, the Axe ad to the left. On first look to most people it probably seems funny, if perhaps a bit cutesy. Upon closer inspection, though, I suspect most people will recognize the code's flaws, but semantic and logical.

For starters, the call to "understand.this" makes no sense. At best, this would likely return a reference to "understand", which makes it redundant. At worst, it's a compiler error. (Both these comments are, of course, somewhat language dependent.) Next, we all know that using the equals operator (==) can be problematic. Further, it seems odd to compare "you" to "understand.this", which are likely different data types and therefore defy comparison. A more logical and semantically valid statement would be:

  1. if( you.understand( this ) ) {

As well, the call to "get.a.girlfriend" is problematic. For starters, the object/property/call chain makes little sense. While it might be work well as a URL, it is clearly an action and therefore (again) should be a method call, not a property/field call. Notice as well that the call operator (()) is missing, which, while valid in a few languages, is generally not acceptable. Again, the perhaps correct way of writing this would be:

  1. you.get( girlfriend );

Or, perhaps:

  1. you.getGirlfriend();

Or we could go all the way, abstract it out a bit more, and go with:

  1. you.getFriend( Gender.Female, Interest.Romantic );

Rolling that up into a complete block, you wind up with:

  1. if( you.understand( this ) )
  2. {
  3.      you.getFriend( Gender.Female, Interest.Romantic );
  4. }

'Nuff said...

(Thanks to Kelly for the original link to the ad - http://cerium50.niloo.fr/18-10-2008/creatives-ads-volume-3/)

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

Why Constants Just Do Not Replace Enums

(Or, one of the many things that ticks me off about Actionscript 3...)

Seems like every time I talk about Actionscript, I'm ranting about something or other that's just ticking me off. I have to start posting about the things I love about it. [ed. I started this post a long time ago and haven't gotten around to finishing it until now. sue me.]

Well, not tonight [ed. today]. Soon, though, I promise.

One of the cool additions to AS 3 is the const keyword. Compile time constants are a beautiful thing. And right off the bat, Adobe started using constants all over the place. In many places, as simulated enums. This is cool, this is good, very excellent.

The big problem is that it misses the point. Enums aren't simply a way of ensuring that you don't make a type-o, letting the compiler throw an error at you because you once again incorrectly spelled "eneterFrema" (yes, I know you spell "spelled" s-p-e-l-l-e-d, I'm employing some sort of literary device, can't remember which, deal with it). Enums are there to make you code a) easier to read and b) easier to write.

I'll illustrate with an example:

GradientGlowFilter (well, actually, you can go with pretty much any bitmap filter on this one, but I'm going to use GGF for a few reasons: firstly, it doesn't include BitmapFilter in it's name, secondly, it's the one I ran into this particular issue with, so there).

The gradient glow filter constructor has the following prototype:

  1. GradientGlowFilter(distance:Number = 4.0, angle:Number = 45,
  2.      colors:Array = null, alphas:Array = null, ratios:Array = null,
  3.      blurX:Number = 4.0, blurY:Number = 4.0, strength:Number = 1,
  4.      quality:int = 1, type:String = "inner", knockout:Boolean = false)

Specifically, I'm looking at the "type" parameter. It's typed as a string, but it only has three possible values, namely, BitmapFilterType.FULL, BitmapFilterType.INNER, or BitmapFilterType.OUTER. You'll notice the default value for the parameter in the constructor above is the string literal "inner". That should have been, at the least, BitmapFilterType.INNER. That would get across (in applications like FlashDevelop and, yes, even in the Flash IDE [ed. you don't actually use the Flash IDE to write code, do you? Seriously...]) that, even though it's using constants and not enums, the value must be one of the constants on the BitmapFilterType class. Same holds true for the quality parameter. It's typed as number, default value is 1, and it needs to be a member of the BitmapFilterQuality class.

Moving to enums would solve this in two ways. For starters, it would be type-safe (eg: if you tried to pass a string, it would break at compile time). And it would be self-documenting, in that by looking at the method prototype you would immediately know what your possible values are and where to find the enum. (Never mind that naming the parameter "type" is ridiculously unhelpful...at least naming it bitmapFilterType would have cleared up what the parameter is there for.)

The truth is, these aren't huge issues, and one could argue that the additional overhead of using an enum-type of class (a la my examples posted previously) adds overhead that isn't absolutely necessary, in the form of properties, etc), but for my money the developer ease of use and clarity far outweighs that (I can't imagine there would be a huge performance bottleneck by having constants that are instances of a class instead of raw strings).

To me, the constructor prototype for this should have been:

  1. GradientGlowFilter(distance:Number = 4.0, angle:Number = 45,
  2.      colors:Array = null, alphas:Array = null, ratios:Array = null,
  3.      blurX:Number = 4.0, blurY:Number = 4.0, strength:Number = 1,
  4.      quality:int = BitmapFilterQuality.LOW, bitmapFilterType:String = BitmapFilterType.INNER,
  5.      knockout:Boolean = false)

Sure, I can look at the documentation and get the answer in seconds, but that's still seconds where I'm second guessing myself.

The other example I was going to bring up was event types (eg: new Event( Event.ENTER_FRAME ) - I finally saw an example last week of using string names for events where it actually made sense to use strings, as opposed to a fully-typed event model, but never mind that). My biggest problem with the implementation, truth be told, is the lack of consistency with where the event type constants are housed (eg. where are the packages for event types? why is ACTIVATED a constant on the Event class, but ACTIVITY is a constant on the ActivityEvent class? Why aren't ADDED and ADDED_TO_STAGE on the DisplayEvent class (which doesn't exist, ttbomk)? why are they all over the place? the list goes on...).

My point with all this is that time and time again, the Actionscript BCL does developers gross injustice by not implementing API's that are consistent and usable. Adobe should make it mandatory that every developer on the team have a copy of Framework Design Guidelines sitting on their desks.

I should probably say, again, that I really do love Flash and where it's going (and where it's been), but as it matures, these are the issues that are going to differentiate it from the other offerings (Silverlight? maybe, I don't know...they do really come at it from different angles, but hey...). And that's not me saying the Silverlight API's are perfect (truth be told, I haven't done much with them, so I can't really offer an opinion there).

Allright. Enough of a rant. Next time, I'm going to scream about the Sound API. Argh. Lovely capabilities. Scary API. Seriously. Scary.

Seeya next time, on J's Bitchings About Things Not Many Other People Care About (But, In His Opinion, They Should).

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

Plantronics 590, Sony Ericcson w810i, and A2DP

Way back in March, my car was broken into and my laptop (along with a variety of accessories) was stolen. My insurance replaced the laptop (with some fairly sweet upgrades along the way), but I'd been holding out on replacing some of the other accessories, mainly in order to get the best possible product for the replacement (yes, I know - a complete waste of time with computer parts).

In any case, I finally replaced my headphones yesterday - picked up the Plantronics Pulsar 590E (E for "Everything including the headset", if by everything you mean the headset, heh). They absolutely rock - I've had them plugged in (and by plugged in I mean hooked via Bluetooth) to my laptop all day: the audio is excellent, latency is low (watching movies with them is definitely doable), connecting was simple (aside from that turning the headset off and hitting play in Winamp caused some minor issues attempting to access a no-longer-existent device) - all in all, you could say I'm in love.

Do yourself a favour and pick up a pair. (And thanks to Martin for turning me on to them in the first place.)

What is pissing me off, however, is the fact that my Sony Ericsson w810i does not support A2DP, and therefore will not play audio via Bluetooth. Making/receiving calls over Bluetooth? No problem. Play audio? Nope. Out of luck.

I suppose this is my fault. I didn't check the spec when I picked up the phone - I would have noted fairly quickly that A2DP is not supported. However, I'm not the only SE user to be frustrated by this, and SE is apparently not upgrading the firmware to support A2DP.

I'm not blaming myself entirely, though. Browsing through the SE site, I can see where I was mislead. The product page for the w810i has a Bluetooth section, and on it it states:

Listening is a pleasure
Pump up the volume with confidence when listening to your favorite song – your Bluetooth&trademark; device will automatically mute the music for incoming calls. There’s no need to lunge for the volume control.

You can check that out yourself at sonyericsson.com.

I guess, though, that they're on the money. The audio is in fact automatically muted for incoming calls. Namely because it was never playing in the first place.

Luckily, the 590 supports multiple connections, so I can have the laptop pushing audio and still take calls via the headset, and it does mute the audio for me...

Sony Ericsson, if you're reading - please upgrade the firmware. And, to be fair, other than this issue, I do love the phone.

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

Revenge of the Waffle

To the uninitiated, the waffle is simply a nice breakfast treat. They come in many flavours (buttermilk, blueberry, cinnamon, you name it), and, add a bit o' syrup, maybe some butter, and you've started your day with a warm and delicious meal.

But there is a darker side to the waffle. Perhaps you don't work alone. Perhaps you don't lock your computer. Perhaps on occasion the rest of your office gets an email from you that looks suspiciously like something you wouldn't say. Perhaps something along the lines of:

Please come...
… and critique my wardrobe. Your input, thoughts and perspective are extremely important as I try to become a better person. Oh yes. And I'm also buying lunch today.

Now, you may be buying lunch for your office. Which might gain you popularity points (assuming, of course, you're not being obscenely cheap and buying...say...leftovers). But, in the end, your irresponsibility has just cost your co-workers precious time and brain-power, as they scratch their heads and wonder if you really need a wardrobe critique (yes, you probably do, but that's really beside the point).

Moral of the story: lock your computer when you walk away from it. Please.

Got an example of a waffle worth sharing? Throw it in the comments...

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

Benevolent Spam

Spam, Spam, SpamChances are, if you have an email account (aka: you're alive), blog or forum, you get spam. I know I do. There's nothing more gratifying than deleting the mindless junk that comes through one's inbox or comments. (Yeah, right...)

So it's nice to see a bit o' spam that is heartfelt and really quite moving:

Please, do not delete the given message. Money obtained from spam will go to the help hungry to children [sic]ugand

Forgiving the bad grammar and spelling, I'm just glad to see that spammers not simply obsessed with Viagra, Cialis, and hot lesbians looking for my hard ...

... earned cash.

I suppose there's no harm in spamming for charity.

Share me: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati