Tuesday, December 11, 2007

Camera Phones are Everywhere

If you doubt the ubiquity of cameraphones, check out this picture:

Girl with cameraphone at museum

You've got a little girl at a museum in Belgrade, taking a picture of a cool rock with a cameraphone. Five years ago, you would never see a phone with a camera, let alone a child with one. It will be interesting to see what happens now that we can assume that everyone has both a phone and a camera.

Cool times ahead!

Thursday, November 29, 2007

ActiveRecord Columns

It can be hard to keep up on side projects, there are just so many other things around the house demanding attention. This week, I've been spending my time demolishing a brick BBQ/planter in the back yard. I've removed 3 cubic meters of dirt and brick! Last night I finished that, so I started to think about the side project I'm working on. As I did, I thought back to the WTF moment I wrote about a while ago, and I was afraid that I was wrong. Totally wrong. Idiotically wrong in a way that would demonstrate that I am a complete total and utter Ruby on Rails noob.

It's interesting about blog posts. I've added Feedburner so I have a bit better an idea of how many people are reading this. Before, I thought it was just a couple of friends and then only when I bugged them, "Hey, did you see my new post?". Now, it seems I have a readership (albeit minimal).

That means that any mistakes I make here are really, really public and enduring. Of course, for me that's part of the point of the blog. I want to be able to go back and see how my ideas change over the years.

Anyways, back to Rails. I was afraid that this code was wrong:

def update_my_status(user, status) if (a_party == user) self.a_party_status = status else self.b_party_status = status end end

I was sitting there thinking, "Wait a second, Ruby says that data members have an '@' in front of them!", quickly followed by, "Nuts, so, do I edit or delete the previous post?"

Just to be sure, I went and fired up the rails console. Very, handy, much recommended. I modified the code to look like this:

class Call < ActiveRecord::Base def my_status(user) if (@a_party == user) @a_party_status else @b_party_status end end ...

I then called it in the console:

>> call = Call.find(:first) => # >> call.my_status(2) => nil

Whew, off the hook. It seems that Ruby has "method missing" functionality, but not "member missing" functionality. So, when I put an '@' in front of it, ActiveRecord doesn't know to look up the value in @attributes. Interesting, and a bit more learned about the internals of ActiveRecord and Rails.

Wednesday, November 14, 2007

Lying, redux.

Happened to me today:

"The NFS mounts are all broken, what's changed on the server?"
"Nothing"
"Well, obviously something's changed, or else it would work. What's changed?"
"Nothing"
...
Several more times back and forth...
"Listen, it's pretty [bleeping] obvious that you have [bleeping] changed something. What the [bleep] have you changed so that I can fix my [bleeping] systems and get some [bleeping] work done!"
"Take a chill pill, and relax dude!"

Bull? Meet Mr. Red Flag.

The actual problem? They changed the directory layout of the NFS mount, so everything moved around. Amazingly, he was surprised when everything stopped working.

Lesson? I need to realise that although the guy is lying his ass off, I need to walk away instead of rubbing his nose in it. I'm not going to get a resolution. I need to follow my own advice, and give people back their monkeys.

So, in the future, I'll just send a polite email (CC'ing my supervisor, and their supervisor), explaining why no one in the entire support organisation is able to get any work done. Hopefully they'll get it resolved by the end of the day.

Oh wait, just yesterday I gave someone advice because they had a technical manager doing exactly that! What did I say? Oh yeah, "He's looking for a reason to slip his project and he's looking to blame you. He should know how to manage his own development systems."

So, either I look like a dick because I put the beat down on some poor overworked IT guy who seems to have been here late screwing it up in the first place (and then bald-faced lying about changing anything), or I look like a dick because I'm looking to blame someone for my schedule slippages.

Hmm. I think I'll walk away and talk to someone else in the team next time. That guy has managed to flip my idiot bit.

Monday, November 12, 2007

Google's Android

I was looking at the docs for the SDK today. I'm interested to see if I need to get an OpenMoko to play with this sucker. However, I haven't been able to find the OS itself, just references to the eclipse plugin.

Even worse is this quote from the FAQ:

Android does not currently support development of third party applications in native code (C/C++).

Not as open as we had all hoped. I'll keep looking, I hope it gets better.

Sunday, November 11, 2007

Recovering a corrupted Akregator feed list

Akregator has an annoying habit of losing your configured feeds when it shuts down abnormally (as in whenever it's "killed"). It's supposed to have a backup of the file, but it manages to truncate that file too.

However, I've found a second backup of the file, ~/.kde/share/apps/akregator/Archive/feedlistbackup.mk4 It contains some binary data at the top, and then appears to have a several different versions of the opml file.

To recover:

cd ~/.kde/share/apps/akregator/Archive/
cp feedlistbackup.mk4 ../data/protect_my_backup
[shut down akregator]
cp feedlistbackup.mk4 feeds.opml
vi feeds.opml
[remove the binary data at the top of the file, leaving the XML declaration tag and the <opml>...</opml> section. Remove everything from the first </opml> to the end of the file.]
[restart akregator]

Just remember, copy the file as soon as you see the problem, if you shut akgregator down, it will overwrite the backup file when it manages to exit properly.

If that "feedlistbackup.mk4" doesn't look right, you can always try to recover the opml file from the list of sites in the archive. However, it won't be organised into folders, and it will probably have all the feeds you have ever subscribed to.

Wednesday, October 31, 2007

No I don't want to unlock your iPhone for you

Just because I've got one, and I love it, doesn't mean I'll help you with yours. It was hard enough for me to unlock mine that my recommendation on the device is this:

"If you aren't a developer familiar with SSH, firmware, networks, bootloaders, and Unix go buy something else. This device is not for you."

That includes buying one that is already unlocked. You will eventually screw up and be back to using ssh and command line shells.

I've got my own projects, and I really don't want to spend my life unlocking other people's phones when I could be having fun.

So, no, I don't want to help you unlock your phone.

The only person I will help is my wife, and that's because, well, I love her. If you aren't her, I don't love you enough, and you can't afford my hourly rate.

Monday, October 29, 2007

Meetings

I've never been in a meeting that was longer than one hour, or had more than four people that achieved anything. I'm being generous with the hour, too.

Why do long meetings continue to exist? I'm becoming more and more convinced that long meetings are a power play. They exist to re-inforce the importance of the person who was able to convince everyone else to show up. Nothing else. Who needs a four hour meeting attended by 20 people about a project that's late?

I'm curious to hear about situations where they've had a good meeting (decisions made) that lasted more than an hour or a large number of attendees. Do they work for you?

Wednesday, October 24, 2007

Rails, models and modifying columns

I had my first WTF moment with Ruby and Rails over the past couple of days. I'm working on a personal project (you'll see it soon), and I'm using Rails. It's an opportunity to learn a new language, and see if the buzz around Rails is true.

Anyways, I was having problem with a model, here's the code I had:

class Call < ActiveRecord::Base
  def my_status(user)
    if (a_party == user)
      a_party_status
    else
      b_party_status
    end
  end

  def update_my_status(user, status)
    if (a_party == user)
      a_party_status = status
    else
      b_party_status = status
    end
  end
end

My controller looked like this:

 @call = Call.find(params[:id])
 @call.update_my_status(current_user(),params[:status])

This didn't work. No matter what I did, I couldn't modify call. I put a tonne of debug lines in, and eventually got to this:


 @call = Call.find(params[:id])
 @call.update_my_status(@call.a_party, true);
 
 if !@call.a_party_status 
   @call.a_party_status = true
   if @call.a_party_status
      # Hrm, first method didn't work, but the second one did?
   else
      # They both failed!
   end
 end

Amazingly, setting the value outside of the class worked, but setting it inside of the method in the class didn't. I was stumped. Google wasn't any help, it seems this is something that no one else runs into as a problem.

Finally, I found a tutorial that showed me what was going wrong, even though it didn't say it explicitly... It had the following example code:

>> player = Player.new
=> #<Player:0x28ef720 @attributes={"team_id"=>nil, "name"=>nil, "number"=>nil,
"position"=>nil}, 
@new_record=true>

Looking at that, it all clicked. ActiveRecord makes extensive use of the "method missing" functionality available in Ruby. Essentially, it looks at what you are trying to invoke and performs the action on the fly if Ruby can't figure it out itself. That explains what is going on with the "update_my_status" method. Since it is an assignment, Ruby will create a local variable, "method missing" isn't invoked and the class attributes are never changed! The solution? Put "self." in front of the attribute assignments:

  def update_my_status(user, status)
    if (a_party == user)
      self.a_party_status = status
    else
      self.b_party_status = status
    end
  end

That was extremely frustrating. I need to see if there is a "warnings as errors" option. It's also an indication that I need to start working on my own stuff earlier in the evening. My brain seems to shut down after 9:30.

Oddly, it seems that I'm the only one who has this problem. After talking a friend, he said, "I always put self. in front of everything out of convention".

Nuts.

Oh, and Rails? It Rocks.

Tuesday, October 16, 2007

Hey, I found an iPhone bug!

This one would be fun to track down. :) After a week of use, I noticed that the volume control (and slider) weren't as responsive as they used to be. The visual control was no longer smooth, tending to move forward and back. My guess is that the animation was semi-predictive, and then corrected for the true value reported by the hardware. Since there was an increasing lag between the control and the visual update, the phone would appear to visually jerk the volume display. A quick reset and the problem's all gone. I wonder if the 1.1.1 touch has the same problem? I wonder what interupts are firing when a keypress/volume change happens?

Thursday, October 11, 2007

Testing and Testers.

Q: What do you do with a tester that feels his responsibility begins and ends with reporting a fault? Refusing to be involved in the resolution, only in the discovery and reporting.

A: Sack their sorry-ass and hire yourself someone who knows what their job really is.

Sunday, August 26, 2007

Google Search Appliance.

We've just got one here. It sucks. It really shows that PageRank is the secret sauce that makes Google work. Without PageRank, all you have is an unsorted list of documents that contain the keyword. Worse than useless.

So, let's say that you are looking for the design documents for a piece of code. Let's call it Foo. You search for Foo, figuring that the design documents would be considered important and at least listed on the first page.

Nope.

First page is full of release notes for patches that delivered Foo. Then you get test exit reports. Then the list of audit reports showing the customers that have it installed.

This is undoubtedly because it is sorting based on date, and the dates on these files are newer than the ones on the word document. However, release notes have no real importance unless you are searching for them specifically. Same goes for test exit reports. They are both write-once documents. Even the audits are easier to find elsewhere.

I never did find the design document for it. The first architectural document that might even be related was on page 2. It was a 5 page .pdf of diagrams.

Anyways, it just re-affirms my opinions. Google with PageRank? Good. Google Appliance? Terrible.

Saturday, August 25, 2007

Lying...

Seems I'm not the only one who thinks that lying to customers is a bad idea. Seth Godin just caught Home Depot doing the same sort of thing. Do people think that their customers don't compare notes and figure out who's lying and what about?

Wednesday, August 01, 2007

Don't Lie

I remember when I was a child, the worst thing I could ever do was lie. It didn't matter that I broke something, hurt someone or did something bad. It was only when I lied about it that I got into real trouble. Stealing and then lying about it was the worst thing I could ever do (I did it just once). Trust and honesty were indelibly inked into my personality from an early age.

That's why I find other people's behaviour so confusing. I don't understand when people misdirect attention away from the company and back onto the customer. I've seen individuals intentionally lie about faults, with a straight face, and not a hint of shame.

Don't do that. Don't lie to your customers. Your customers will eventually figure it out, no matter how stupid you think they are. Even worse, it will cause confusion in your own team. You know that fault you convinced the customer was their fault? Everyone internally thinks that it's been resolved too. So, when it crops up again, which it will, you've just wasted time, instead of buying yourself some breathing space.

Sometimes you might feel that you really, really need to lie to the customer. O.k. we'll have to disagree there. Even so, if you are going to lie to the customer, make sure that you don't lie to yourselves at the same time.

And understand, if I see you lying, I won't be impressed. I'll think you're an idiot and I won't trust you with anything.

Corollary - Every setting has a reason. If the default has changed, ask yourself "why has that changed?" Don't assume that it was done for no reason.

Monday, April 02, 2007

How to Destroy an Ego

It's about follow through. Everything in life is about follow through. Me, I suck at finishing. I come up with ideas, spend a week writing a rough prototype and then drop them.

However, when I drop something, it only affects me. How about this story for some experiential learning?

One of your engineers approaches you, he says, "Hey, I've got some really cool ideas, should I write them down?".

You agree that the engineer should produce the document, and agree a price. The engineer goes away and produces a proposal document over the next two weeks.

What happens next is the interesting bit. What does it say if you, as the customer for this piece of work, don't provide any feedback? It says:

  1. That it wasn't important enough to read.
  2. If it was read, it wasn't even good enough to warrant a "OMG that's CRAP!" response.
  3. That the whole task was about humouring the engineer, and perhaps giving them a bonus without calling it that.
  4. That the ideas themselves have no value.

Of course, from your point of view, you look at this document and think to yourself, "It's 50 pages! That will take 2 hours to read properly. I've got so many reports to write, bid responses to prepare, I'll look at it next week." Before you know it, it's next year and you think that it's too late to respond. Basically, you've proven to the engineer that all of 1,3 and 4 apply.

What's that going to do to their self-worth? It's not a fatal blow, but it will eat away if they let it. It will certainly affect the relationship you have with them, and they will definitely never, ever step forward with more ideas for your organisation.

So, if someone asks for feedback, make sure you provide it. Even if the feedback isn't positive. It's always better to hear something.