Skip to main content


Showing posts from 2010

Apple: Ouch!

I had my laptop wrapped in a blanket in my backpack when I dropped it on concrete at BART yesterday. It landed on the corner with quite a lot of force and bent a few metal pieces. Everything seems to work, with the exception of the ethernet port. Thankfully, I rarely use that. I'm hoping this is covered by the warranty, although it seems unlikely. The bent aluminum reminds me of body damage on a car.

Vim: PeepCode Videos

There are commercial videos on PeepCode that show how to use Vim. They're fantastic! The production quality is very high, so they're worth paying for. I bought both of them, and I learned quite a lot. Even the first one covered a ton of advanced stuff, so I highly recommend it.

If you're just getting started with Vim, I suggest you:Read this blog post from Yehuda Katz. Basically, he suggests you use the GUI to get started and iteratively gain more experience with Vim. I think that's good advice.Next, I suggest you fire up Vim and take the internal tutorial.Last of all, watch Smash into Vim part I.If you're an advanced Vim user, watch both videos and tell me what your favorite part was ;)

JavaScript: IE and DTDs

I was having a hard time getting Internet Explorer 8 (IE8) working with Socket.IO's "htmlfile" transport (or any other transport for that matter). I was getting weird permissions issues. I finally fixed the problem by adding a DTD to the top of my HTML file, "<!doctype html>". I was just being lazy not having a DTD, but I was really surprised when that fixed my problem. Of course, I'm still having a hard time getting IE7, IE6, and Opera working cross-domain (technically, I'm just using a different port, but eventually it'll truly be cross-domain).

Ruby: Why I Prefer Cucumber

I've been struggling to articulate why, in most cases, I prefer high-level integration tests with Cucumber and Webrat (or Capybara) over low-level model, view, and controller tests with RSpec. I think I finally have an example that conveys what I'm trying to say. Consider the following Cucumber test:Scenario: create a new film unsuccessfully
Given I am logged in as "admin"
And I am on the admin films page

When I follow "New film"
And I press "Create"
Then I should see "There were problems with the following fields:"
And I should see "Name can't be blank"
And I should see "Url name can't be blank"
And I should see "Sort name can't be blank"
And I should see "URL doesn't look like a valid RTMPE URL"
But I should not see "Trailer URL doesn't look like a valid RTMPE URL"
And I should not see "Scene URL doesn't look like a valid RTMPE URL"This tes…

Software Engineering: Coping When You Must Repeat Yourself

These days, most software engineers are familiar with the acronym "DRY" which stands for "don't repeat yourself". In general, it's good advice. In a perfect world, no code would ever be duplicated and every piece of "truth" would only exist in one place. However, the real world isn't quite so perfect, and things are far less DRY than you might imagine. The question is, how do you cope?

First let me show you some reasons why you can't always keep it DRY:

Often, the same truth is duplicated in the code, the tests, and the docs. Duplicating the same piece of truth in the code and in the tests helps each verify the other. Generally, the code is more general than the tests (the tests verify examples of running the more general code), but the duplication is there. When you update one (for instance to change the API), you'll need to update the other. This is a case where not keeping it DRY pays off--if you have to update the tests, that…

JavaScript: Naughty Socket.IO Example

File this under the "things you probably shouldn't do, but are fun anyways" category. Socket.IO is a library for Node.JS that provides Comet using a plethora of different approaches (WebSocket, Flash socket, AJAX long polling, etc.). I hacked the Socket.IO chat demo so that it reads HTML from my terminal and just dumps it to the browser. Hence, I can control people's browsers from my terminal. Insecure? Yeah. Fun? Oh yeah!

Anyway, here's how I hacked the server.js file in Socket.IO's chat demo:io.on('connection', function (client) {

// Read from /dev/tty and send it to the browser.
var stream = fs.createReadStream('/dev/tty', {encoding: 'ascii'});

stream.on('error', function (exception) {
client.send({announcement: 'Exception: ' + exception});

stream.on('data', function (data) {
client.send({html: data});
...And here's how I hacked chat.html:function message(obj) {
var el = document.createE…

Jobs: Looking for People to Work With Me

I'm really enjoying myself here at Twilio. We're looking for a few more people, and I wonder if any of my readers would like to come work with me.

Twilio makes it easy for normal web developers to write voice and SMS enabled applications. If you don't know what I mean, try calling my app: (888) 877-7418. By the way, Jeff Lindsay, the SHDH house guy, is here too.

Here are the positions we're hiring for:DevOps EngineerSenior Software EngineerCore TeamSoftware Engineering Leader, Organizer, MentorCustomer AdvocateDeveloper EvangelistProduct ManagerWe use a mix of Python, Java, PHP, and Ruby. We're in San Francisco. We just closed a second round of funding, but we also make a lot of money.

Here are the actual job postings. Contact Joanna Samuels for more information.

Books: Digital At Work: Snapshots From The First Thirty-Five Years

I just finished reading Digital At Work: Snapshots From The First Thirty-Five Years."Digital At Work" tells the story of the first thirty-five years of Digital Equipment Corporation [DEC] and illuminates the origins of its unique culture. First person accounts from past and present members of the Digital community, industry associates, board members, and friends - plus a wealth of photos from Digital's archives - trace the company's evolution from the 1950s to present.In short, I really enjoyed it. By reading this book, I was able to vicariously experience the growth and history of one of the most significant companies in the history of computing, and it definitely left an emotional impact.

I think one of the most interesting things about Digital was its culture. Some people might call it chaos. Other people might call it a meritocracy. It was definitely in the MIT tradition. It wasn't uncommon to get into shouting matches over which approach to take. Good i…

Linux: The Tiling Window Manager I Wish I Had

Every year or two, I switch to a tiling window manager such as xmonad or dwm. Inevitably, I switch back to GNOME after a couple weeks. Sometimes it's because the window manager doesn't fit in with the rest of my GNOME desktop (it used to be non-trivial to get xmonad to work with GNOME's panel). Sometimes it's because of bugs related to having a weird window manager (NetBeans used to freak out with xmonad, and Flash refused to go full-screen). Every time I try again, a bunch of things have improved. xmonad even had a project aimed at making it more accessible to GNOME users. Still, I think the biggest problem I have is that tiling window managers make some assumptions that just don't work out for me in practice.

I use more than just terminals. I still like to use things like GVim, the GIMP, Google Chrome, a graphical chat client, etc. In fact, I even get a real kick out of writing GUIs. Some tiling window managers assume you're going to live in a termina…

JavaScript: A Second Impression of NodeJS

When I first heard about NodeJS, my reaction was, "Why would I use JavaScript on the server when there are similar continuation-passing-style, asynchronous network servers such as Twisted and Tornado in Python already? Python is a nicer language. Furthermore, I prefer coroutine-based solutions such as gevent and Concurrence." However, after watching this video, Ryan Dahl, the author of NodeJS, has convinced me that NodeJS is worthy of attention.

First of all, NodeJS is crazy fast. Dahl showed one benchmark that had it beating out Nginx. (However, as he admitted, it was an unfair comparison since he was comparing NodeJS serving something out of memory with Nginx serving something from disk.) It's faster than Twisted and Jetty. That last one surprised me.

Dahl argued against green thread systems and coroutine-based systems due to the infrastructural overhead and magic involved. He argued that he doesn't like Eventlet because it's too magical both at an implem…

Telephony: Blatantly Open Source Phone Trees

As I mentioned in my last post, I just launched Teladventure, a phone based adventure game. (The phone number is (888) 877-7418.)

Anyway, I added a "learn more" menu option to the phone tree. It says:Teladventure was created by Shannon -jj Behrens using Ruby on Rails and Twilio. Please feel free to submit feedback to the author by emailing him at j,j,i,n,u,x,at,g,mail,dot,com.

Teladventure is open source. You can get the source code from git,hub,dot,com,slash,j,j,i,n,u,x,slash,t,e,l,adventure.(The commas are there to help the text to speech engine.)

Why am I bringing this up? When was the last time you called a phone number and got a phone tree that told you that it was open source and gave you the URL to download it? ;)

Teladventure: A Phone-based Adventure Game

I just finished building a phone-based adventure game. The number is (888) 877-7418 (which is a toll free number). The code is here: Give it a shot!

I used Ruby on Rails, behavioral-driven development (with Cucumber), and Twilio. However, these same tricks work in Python too since Twilio is language agnostic.

Check out my previous post about using behavior-driven development to build phone trees.

Ruby: Phone Trees

I just finished building my first, fully-functional, non-trivial phone tree. This is exciting because it only took me two days. It has a bunch of submenus, it records and plays back content from the user, and it's even pretty friendly about confirmations.

I built it using Ruby on Rails and Twilio which is where I just started working. Building a telephone app using web technologies is very comfortable.

What's most amazing is that I used behavioral driven development using Cucumber in order to develop the app. In fact, I didn't even call my app until I had finished building it. It was mostly correct the first time I called it. Using Cucumber to walk through all the user-flows in the phone tree was a big win!

Note, I didn't use one assertion per test as I warned against here, but rather wrote very full integration tests that walked around the phone tree quite a bit. Here's an example test that actually interacts with the phone tree:Scenario: delete a friend, but …

Rails: Fat Tests Considered Unharmful

How many assertions should a test have? For instance, how many times should you use ".should" in an RSpec test? How many times should you use "Then" in a Cucumber test?

I have seen some developers work very hard to never have more than 1-2 assertions per test. They consider tests that are more than 3 lines long to be a code smell, and they tend to break up tests so that there is one assertion per test. I'd like to suggest that this conventional approach has some downsides that are too often overlooked.

First of all, what are the upsides of super skinny tests?

If you put 10 assertions each into their own test, then you can get very fine-grained results concerning which tests pass and which tests fail. That's useful. However, fine-grained results aren't all that crucial. I actually don't care all that much whether one test fails or ten tests fail. It doesn't really tell me how many bugs there are. Either way, it could be a single misspelling…

Personal: Fandor is Launching

The site I've been working on for the last year, Fandor, is finally ready! If you like independent and international films, you might want to check it out. Fandor is a subscription service for streaming independent films on demand. As we move into a new phase, we are inviting our friends and family to sign up for a one-month free trial.

To sign up, go here and fill out the quick subscription form:

This is the first version of the site, so we anticipate many changes to come. Please don't hesitate to give feedback. Your comments and questions will be very helpful as we shape the service. By the way, no it wasn't my idea to require a credit card before you can look around on the site ;)

Have fun!

Tailing Whitespace

Here's how to get rid of trailing whitespace from all your files:# Strip trailing whitespace from files that end in .as.
# Change this to match your programming language.
# I'm not sure if the -i flag is supported by all OSs.
find . -name '*.as' | xargs sed -i 's/ *$//g'

# See if the changes look reasonable.
git diff

# There should be no changes that aren't whitespace changes.
git diff -w

Quotes: A Recruiter on Scala and Erlang Jobs

I got the following from a recruiter today:Scala (and erlang while we're at it) roles are like UFO's, there are always sightings of them, but I just don't think they're real. :)That's a pretty funny quote ;) It just reminds me of the fact that jobs are a trailing indicator of a technology's success. For instance, there are currently five jobs for COBOL on Craigslist, which is actually the same as the number of Scala jobs on Craigslist.

Quotes: Mark Twain on Math

"In the space of one hundred and seventy-six years the Mississippi has shortened itself two hundred and forty-two miles. Therefore ... in the Old Silurian Period the Mississippi River was upward of one million three hundred thousand miles long ... seven hundred and forty-two years from now the Mississippi will be only a mile and three-quarters long. ... There is something fascinating about science. One gets such wholesome returns of conjecture out of such a trifling investment of fact."
-- Mark Twain

Quotes: Max Levchin on Startups

"The very first company I started failed with a great bang. The second one failed a little bit less, but still failed. The third one, you know, proper failed, but it was kind of okay. I recovered quickly. Number four almost didn’t fail. It still didn’t really feel great, but it did okay. Number five was PayPal."
-- Max Levchin

Scala: Using Akka with Play

Here's a screencast of using Akka in the context of Play. Akka's motto is, "Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors". The screencast shows how to implement a hit counter using STM (software transactional memory). It's acting as a library within the context of a Play application. That surprises me (in a good way) since I was afraid you'd have to run Akka out of process. The screencast shows how STM is able to maintain correct results under a heavy, concurrent load. It looks pretty painless. There's another screencast showing how to do the same thing with actors, and then another that shows how to do the same thing for a cluster of servers using remote actors.

Java: The Play Framework

I just watched a screencast for the Play framework. It's motto is:Finally a Java framework made by Web developers. Discover a clean alternative to bloated enterprise Java stacks. Play focuses on developer productivity and targets RESTful architectures.All I have to say is wow!

I plan on using Play using Scala instead of Java, but nonetheless, I'm completely amazed at how friendly, efficient (to develop), and polished it is. The API looks very much like Rails, and so does the development process. For instance, you just edit files and hit reload. Compile errors are shown directly in the browser, using a beautiful interface. The MVC approach and file layout looks like Rails, however there's an admin interface that looks like Django.

I've heard multiple people say that you can go from not knowing Play at all to having something working to show to your boss in about two days. Best of all, Play has put a lot of effort into its Scala bindings. I hate to sound like a fan …

Scala: Lift vs. Play! For Web Development

If you're interested in doing Web development in Scala, have a look at my Stack Overflow question and even more importantly this thread that I started on the Bay Area Scala Enthusiasts mailing list.

In it, there are some choice quotes from David Pollak such as:In terms of Lift and older browsers, Lift doesn't support them (or at least it doesn't support them well.) At the end of the day, in order to use a Lift app, you need a modern browser (IE 6+, Firefox 1.5+ or WebKit-based [Chrome, Safari])...

Put another way, with 99%+ of the apps people are writing in Lift, they will live in a single JVM...

[When I asked whether a user's session (such as the contents of his shopping cart) was lost when new code was deployed to the server because of the statefulness of Lift, David said] Most of the site deployments that I do in production are during well defined maintenance windows in which the entire service is shut down. I realize that there's a class of services for which th…

Personal: I'm a Wireless Black Hole

My wife and I both have Samsung Moment cell phones running Android on Sprint's network. I always complain that I can't get reception in the house, whereas her reception is always fine.

Today, we did an experiment. She had 4 bars on her phone. She passed her phone to me, and it dropped down to 0 bars. I gave it back, and she had 4 bars again. I decided to sit in her seat. I still only got 1 bar.

What the heck? The only thing I can think of is that she's really small, and she's a bit on the anemic side, whereas I'm fairly large and I have an abundance of iron in my blood. Does that even matter?

We just conducted the experiment again, standing next to each other, with the same results. The way we hold the phone doesn't seem to make a difference. We're both barefoot.

Rails: reset_session and Webrat Don't Play Nicely with One Another

All the Rails security guides say that you should call reset_session after the user logs in or logs out. This clears out the session and forces a new session ID to be created. It seems there have been a few Rails bugs related to reset_session over the years.

In my login action, I call reset_session and then put a nice message in flash. When I actually use the website, I can see (via Firefox) that I'm getting a new session ID, and I can see my flash message. However, when I write tests for those two things, the flash message gets lost, and I don't get a new session ID in my cookies. It's almost as if the new session is being ignored, and the old session is being used.

I submitted a bug to Webrat about this, but it turns out it's an issue in Rails. This issue is present in version 2.3.8. If this is affecting you, there's a workaround here. I implemented the workaround, and it worked like a charm :)

Ruby: Blooger

I needed some sample code for an interview, so I built a website called Blooger. It's a site (like Blogger) where people can go create a blog to blog about their booger stories. It even has functioning Atom feeds :)

Here's the source code. I used Cucumber, RSpec, Webrat, and factory_girl to do behavior driven development. I used Authlogic for authentication. I used BlueCloth for Markdown support in order to format the blog posts. The README in the source has more details.

Books: Programming Scala

I just finished reading Programming Scala. In short, I really liked it.

The first few chapters are breathtakingly fast. Some of the middle chapters are kind of slow, but are still worthwhile. Scala is a fairly large language (unlike, say, Scheme or C), and the book is a fairly dense 400 pages. I found it helpful to read slowly and take notes.

As for Scala itself, I really like it! Scala is a nice mix of Java, C#, Erlang, Haskell, Ruby, and Smalltalk. You can treat it as a "better Java", or you can treat it as a more enterprise-friendly Haskell. Either way, it's exactly what I was looking for: a language with reasonable syntax, an ML type system, and a decent set of real world libraries. I know that the Haskell community is working hard in this direction as well. I think Scala stands a very good chance at being a work-friendly, programmer-friendly language.

I'm a little afraid that its type system may be too large and too complex for a lot of programmers. To b…

Personal: Looking for Work

I'm looking for a new job. As much as I've enjoyed my time at my current company, I'd like to move on to something new.I'd like to give Scala a shot, if possible. For the last year, I've been doing Ruby on Rails, and before that I was doing Python. I've been learning Scala in preparation of making the transition.I'm only looking at companies in San Francisco or the East Bay.I prefer behavior driven development and really clean code. I'm really bad at working on sloppy code bases with no tests and no documentation.I prefer Linux.I have a predilection toward startups.Here's my resume. Thanks!

Scala: Tweet Tweet Tweet

I'm almost done reading Programming Scala. I've really enjoyed the book as well as Scala.

One of the lead developers is Alex Payne who is a lead developer at Twitter. I'm very impressed with his stuff, but having read the following piece of code from the book, it really makes me curious what the Twitter code base looks like ;)def saveTweet(tweet: Tweet) = tweets ::= tweet

Flash: I Like Wowza

I like the Wowza Media Server better than Adobe's Flash Media Server.It costs less.So far, it seems less buggy.Plugins for it are written in Java, which is more pleasant than server-side ActionScript. Server-side ActionScript is very different than ActionScript 3 (which I actually like).The API seems nicer.It has a very nice admin and monitoring system--Java's standard--jmx.The server can simultaneously support streaming the Adobe way (RTMP, etc.), the Microsoft way (smooth streaming), and the Apple way (HTTP live streaming). It supports all three including bitrate switching all from the same source files.The one missing feature that it doesn't support is SWF verification. It does support something called secure tokens, but I can make a pretty decent argument that SWF verification is more secure (at least for my use case).

Credit goes to Dan Aronson for a lot of this content.

Software Engineering: Premature Featurization

"Premature Featurization" is my term for the tendency to implement a plethora of features before they've even been requested by real users just in case a user might want them.

It's related to creeping featurism. Like premature optimization, it leads to difficult-to-maintain code bloat.

Product managers and managers in general are especially prone to premature featurization. When experienced developers themselves fall prey to premature featurization, they may be suffering from second system effect.

To some degree, the opposite of premature featurization is creeping elegance, which is where an existing piece of code is polished excessively at the expense of other factors such as the schedule or real world features.

It should be pointed out that agile software development aims to prevent premature featurization in that it forces coders to code only those features that the stake holders have requested as they request them. However, it tends to be an enabler for premature …

Linux: Retro Desktops

I like messing around with my desktop. I decided to give it a retro Windows look. I used the Redmond theme, set all my fonts to Monospace 10, used a boring gray background, and tweaked my editor and terminal colors.

Now I know that Windows 2000 didn't use monospace fonts for everything, and it supported backgrounds other than a drab grab, but doing it this way sets a pleasant, calm, nostalgic mood.

What's strange about this 1 AM post is that a) I've been a Linux user for so long that I've never even used Windows 2000 b) I'm using Mint Linux which aims at offering a very elegant, polished look--which I've totally screwed up ;)

By the way, what I'd really like is a desktop that looks like the original Macintosh. That'd be pretty neat looking for this MacBook running Linux ;)

Ok, yes, I probably need to get a life, but I wonder if there's anyone else out there who likes retro looking desktops.

Apple: Cleaning a White MacBook

In a moment of reckless abandon, I decided to clean my white MacBook today. I wash my hands almost every time I use my laptop, but oil from my hands still builds up and attracts dirt. This leads to very irritating grime. Ordinary water won't due the trick, so I decided to tempt fate and use something with bleach. I'm pretty sure that voids my non-existent warranty.

I sprayed some Easy Off BAM Multi-Surface Power Cleaner with Bleach onto a damp paper towel and then rinsed out the paper towel a couple times. I squeezed as much water out of the paper towel as possible, and then I wiped my keyboard, etc. clean. I didn't put the cleaner on the screen--I'm not that brave ;) Then, I took a microfiber towel, wet it, and wiped down the whole laptop. Then, I used a dry part of the same towel and dried it completely.

The wet microfiber towel always does a good job with the screen. The cleaner did a great job with the grime. Some of the keys are still shiny (presumably fro…

An Email Scam

My wife encountered an email scam that I had never seen before. She got an email from a friend's email address:I'm caught up in a real mess and i need your help. I'm sorry I didn't inform you about my trip,I had a trip to the Wales United Kingdom and a bizarre thing happened to me.I was mugged at gun point last night, it happened at the park of the Hotel were i lodged but thank God i wasn't hurt, the muggers carted away with all my belongings excluded my passport. Cell,credit card,cash and some important documents are all gone. I was able to make contact with the UK Police and i was directed to the Embassy, but they seems to be taking things too slow.I need your help so urgently.. My flight leaves pretty soon but i am having problems sorting out the hotel bills also getting my ticket straightened out. Ineed your help. I need a quick loan of ($1,800) to get things fixed out here,I promise to refund as soon as i get back home.. please reply asap. so i can tell you…

Ruby: rails_xss

There's a new plugin called rails_xss:This plugin replaces the default ERB template handlers with erubis, and switches the behaviour to escape by default rather than requiring you to escape. This is consistent with the behaviour in Rails 3.0.

Strings now have a notion of "html safe", which is false by default. Whenever rails copies a string into the response body it checks whether or not the string is safe, safe strings are copied verbatim into the response body, but unsafe strings are escaped first.This is a nice feature that I used to like in other templating engines, so I'm glad Rails now has it as well. I just updated my code to use it, and things went relatively smoothly. I deleted all the useless calls to "h()" and added "raw" or "html_safe" in all the right places. Thank goodness for tests ;)

A Few Simple Ruby, Rails, and MySQL Tips

Sometimes it makes sense to store the value of a query in a variable within MySQL. You might do this if you're avoiding ActiveRecord because you're in a data migration. Here's how: execute %{SELECT (@setuid_id:=id) FROM roles WHERE title = 'setuid'};
execute %{SELECT (@admin_id:=id) FROM roles WHERE title = 'admin'};Similarly, sometimes it's helpful to use the results of a query in order to insert several rows at the same time. MySQL has INSERT...SELECT syntax that can be used like this: execute %{
INSERT INTO roles_users (role_id, user_id)
SELECT @setuid_id, user_id
FROM roles_users
WHERE role_id = @admin_id
}The above query finds all the admins and gives them the setuid role as well.

If you're a Python coder coding in Ruby, don't forget that ["a", "b", "c"] is more simply written %w(a b c).

You probably know that you can lookup rows via ActiveRecord finder methods like Role.find_b…

IDEs: Netbeans

As I've mentioned before, I use Netbeans with the jVi plugin. It's enough IDE to improve my productivity without being so much that I feel overwhelmed. Using the jVi plugin makes a Vim fanatic like me feel right at home.

Just in case it's helpful, here's my NetBeans setup (in outline form):Setup NetBeans:
Downloaded the Ruby pack.
It's a shell script. Run it as root. Don't install GlassFish.
It installs to /usr/local/netbeans-6.8.
To uninstall: /usr/local/netbeans-6.8/
There is a menu item to run it.
After install:
Installed the Python plugin:
Jython distribution.
Installed the PHP plugin.
Installed the Cucumber Features plugin.
Installed the nbgit plugin by downloading it manually.
Installed the jVi plugin by downloading it manually.
Setup jVi:
Tools >> Options:
Buffer Modifications:
bs: 2
sts: 2
sw: 2
Control-Key Bindings:

Ruby: Using reset_session in Rails with Cucumber and Webrat

I filed the following bug:All the Rails security guides say that you should call reset_session after the user logs in or logs out. This clears out the session and forces a new session ID to be created. It seems there have been a few Rails bugs related to reset_session over the years. However, I'm now worried that there's a conflict somewhere related to Rails' testing infrastructure and/or Webrat.

In my login action, I call reset_session and then put a nice message in flash. When I actually use the website, I can see (via Firefox) that I'm getting a new session ID, and I can see my flash message. However, when I write tests for those two things, the flash message gets lost, and I don't get a new session ID in my cookies. It's almost as if the new session is being ignored, and the old session is being used.

I'm sorry, but I can't tell exactly where the problem is. I know that there's special Rails code that handles session cookies when you're doing …

Linux: Qimo for Kids

I just installed Qimo, an Ubuntu-based distribution for kids. If you already have Ubuntu, just run "apt-get install qimo-session".

I just started poking around, but I like it already. I had Edubuntu previously. For some reason, this seems simpler, neater, easier, and more engaging. I think Edubuntu has everything Qimo has, and more, but Qimo presents it in a more compelling manner.

By the way, Qimo doesn't provide parental controls, so you'll have to install something extra if you're into that sort of thing.

ActionScript: JavaScript Event Handlers for JW Player

JW Player has a rich JavaScript API. One of the things you can do is to create JavaScript event handlers for ActionScript events. However, there are a few things that can bite you in the butt if you don't keep them in mind.

First of all, as the documentation points out, you can't set an event handler until JW Player is ready for it. If you set it too early, it won't work, and you won't even get an error message. If you have a function called playerReady, it'll automatically be called by JW Player. That's a great place to setup your handlers.

Next, when JW Player calls playerReady, it's supposed to pass an obj containing the ID for the HTML DOM object. In my experience, it doesn't. Hence, you have to lookup the object manually. See my previous post about the fact that you can't use jQuery's $() to lookup the object, but should instead stick with document.getElementById.

Last of all, remember that when you give JW Player your JavaScript callb…

ActionScript: jQuery and ActionScript Callbacks

Let's suppose you have a SWF, and you're calling callbacks on that SWF from JavaScript. The following works:document.getElementById('id-of-your-embed').someActionScriptCallback('someJavaScriptCallback')The following doesn't work, and there is no error message:$('#id-of-your-embed').someActionScriptCallback('someJavaScriptCallback')I often think of $() as a way to use document.getElementById, but since it returns a jQuery shim, some things don't work as expected. This one took me quite a while to figure out.

Neuroscience: Burn-out Visible in the Brains of Patients

I just found this on Hacker News: Burn-out visible in the brains of patients. Since I've suffered from burnout for about a decade, this comes as no surprise to me.

Try to do pushups until you can't do any more. Now, wait a minute, and then do 50 more pushups. That's the best way I can explain what burnout feels like--my brain just feels like jello a lot of times.

I'm sure a lot of other programmers have to deal with this just like I do.

Apple: iPad and Emacs

Someone asked my boss's buddy Art Medlar if he was going to buy an iPad. He said, "I figure as soon as it runs Emacs, that will be the sign to buy." I think he was just trying to be funny, but his statement is actually fairly profound.

It's well known that submitting iPhone and iPad applications for sale on Apple's store is a huge pain--even if they're free and open source. Apple is acting as a gatekeeper for what is and isn't allowed on your device. I heard that Apple would never allow a scripting language to be installed on your iPad because it would allow end users to run code that they hadn't verified. (I don't have a reference for this, but if you do, please post it below.) Emacs is mostly written in Emacs Lisp. Per Apple's policy, I don't think it'll ever be possible to run Emacs on the iPad.

Emacs was written by Richard Stallman, and it practically defines the Free Software movement (in a manner of speaking at least). Stal…

Books: The Little Schemer

I just finished The Little Schemer. I liked it. It's a very short book. Most of my time was spent doing the exercises, which were very worthwhile. There were a few sections I had to read twice, but the book was far more accessible than say SICP. If you've never coded in Lisp or Scheme or if you're looking for some good exercises for your coding fu, I highly recommend this book. Happy hacking!

Python: The Halting Problem

I've been reading The Little Schemer, and I particularly enjoyed learning about the halting problem. I enjoyed learning about it so much that I figured I'd take the time to explain it in Python so that other Pythonistas could enjoy it with me ;)

Let's suppose I have two functions:def does_stop():
return True

def does_not_stop():
while True:
passdoes_stop does stop. does_not_stop does not stop. How do I implement the following function:def will_stop(f):
"""Return True if the function f eventually stops, and False otherwise."""
...Let's suppose for a moment that I can implement such a function. Now, let's look at this function:def just_might_stop():
return will_stop(just_might_stop) and does_not_stop()Does just_might_stop stop or does it continue forever? That is, what is the value of "will_stop(just_might_stop)"?

Well, I don't know yet, but let's suppose that "will_stop(just_might_stop)&quo…

Scheme: My Y Combinator

I've been reading The Little Schemer, and it posed an interesting question: how can you create a recursive function without having the ability to "define" a name for it? For instance, in Scheme, how can you create a simple, recursive function to calculate the length of a list without having the ability to use "define"?

Here's my approach:((lambda (my-length l)
(my-length my-length l))
(lambda (my-length l)
((null? l) 0)
(else (add1 (my-length my-length (cdr l))))))
'(1 2 3 4 5))The outer function is "(lambda (my-length l) ...)". It takes a reference to a function that it calls my-length. It calls that function "(my-length my-length l)". Hence, that function, which I call "my-length", receives the list as well as a reference to itself, "(lambda (my-length l) ...)". Since it receives a reference to itself, it's able to call itself recursively.

It turns out the real answer is called the…

Humor: An Environmentally-friendly Desktop

In an effort to be more environmentally conscious, I've decided to make my desktop more green. And although my sympathies lie with California's Central Valley farmers, I've also decided to show my support of the delta smelt by switching to a shell called "fish".

Do I think my actions will solve global warming? No--but it's important for each of us to do our part!

Linux: fish: The Friendly, Interactive Shell

I'm trying out a new shell called fish. Here are some screen shots and here is a great article to help you get started.

Usually, I'm a zsh user. fish aims to be as powerful as, say, zsh, but a heck of a lot easier to use and a lot easier to learn. So far, that's proven true. The shell provides intelligent tab completion, syntax highlighting, helpful error reporting, integrated documentation, etc.

Fish is inspired by Bourne shell syntax, but is not compatible with it. Specifically, a lot of ugly things have been cleaned up and made more regular. I do think that the syntax is nicer, although it takes a while to get the hang of if you're already a shell expert. About the only inconvenient part of switching to fish is that I can no longer copy and paste complicated bash one-liners from various places online.

The documentation is excellent. However, you might find this cheat sheet helpful for getting started:help:
: Get help with using fish.
Searching through history:

Ruby: Modifying Class Attributes in Cucumber and RSpec

Imagine you're building, and you have a rating system. You might not want to show an average rating to the user until there's been some minimum number of ratings. Of course, you'll want to test that that feature works. However, in other tests, you might want to disable that feature by setting the minimum number of ratings required to 0.

More generally, I sometimes run into the situation where I have a constant in my model that I might want to change, but only for a specific test. Instead of using a constant, you can use a class attribute. However, since class attributes aren't part of a database transaction, they don't get reset after every test. That's a problem since one test that changes the class attribute might mysteriously break another test that relies on that class attribute. I had a problem where one feature file would pass when run alone, but it wouldn't pass when all the features files were run. Here's how to make it all wor…

ActionScript: Dynamic Streaming

There's an article here about dynamic streaming in Flash Media Server 3.5 using Flash 10's new QoS features. It's a three-part series, and I just spent several hours reading it.

It talks about a class that Adobe provides called "DynamicStream". It doesn't come with ActionScript 3.0--it's a separate download. I was hoping to integrate this class into JW Player in order to do more intelligent bitrate switching using Adobe's new QoS features.

Let me explain why I'm frustrated.

First of all, this article was a three-part series, each with several pages. Hence, it was very long--much longer than I think was necessary. Part 3 covered "Integrating dynamic streaming with existing video players". Since it was the final page in the entire series, I expected it to be very exciting and useful. Instead, it was very mediocre. I can summarize, "Hey, this stuff doesn't work in Flash 9, so you'll have to do something else to support old…

Science: Gravity as a Communications Mechanism?

Does gravity move at the speed of light? For instance, if I were able to change some energy into matter, how long would it take for other matter to begin to feel the attraction of the matter I created? I assume someone out there knows the answer.

If you could convert energy to matter and back again in an amazingly concise manner, and do it at a specific frequency, and if you could detect such changes in gravity at a specific frequency, you could conceivably use gravity as a communications mechanism. That's not likely to happen during my lifetime, but it does make for some interesting science fiction.

Books: ActionScript 3.0: Visual QuickStart Guide

I finished reading ActionScript 3.0: Visual QuickStart Guide. All-in-all, it wasn't bad. I needed to learn ActionScript quickly, but not extremely deeply, and it helped me do that.

This is the first time I've read a visual quickstart guide. The book was only about 300 pages, and each page was cut in two columns. The inner columns have code, and the outer columns have prose. Hence, there's only about 150 pages of prose. The code tended to be very basic and very redundant. Unsurprisingly, the author was a non-software engineer who learned how to code in ActionScript. I sort of expected that. The book wasn't perfect, but I definitely recommend it if you're a software engineer who needs to learn ActionScript in a hurry.

That's enough for the book review. Now, let me say a few words about ActionScript. First of all, ActionScript 3.0 is a compiled language. ActionScript started life as ECMAScript, but by the time they hit 3.0, it had morphed into a pleasant…

Python: Is there a Python Toolbox Website?

Is there something like Ruby Toolbox for Python? Unlike PyPI, Ruby Toolbox feels highly curated, which I really, really like. Notice it even has graphs to show you the relative popularities of the various packages.

Half the reason I go to PyCon is so that I can know which libraries are good, and which ones aren't so good. Ruby Toolbox helps me cut to the chase, so it'd be great to find something like that in the Python world too.

Ruby: Interesting Things from the Rails Book

Here are a few interesting things I stumbled across while reading the Rails book recently:

Use debug(object) to dump an object to the screen in a template.

Here's how to use the debugger to debug your web app. First, "gem install ruby-debug". Then, start the server via "./script/server --debugger". Now, add "debugger" in your code.

Use "rake --tasks" to see the full list of rake tasks available.

Use "rake --describe task" to describe a particular task.

David Heinemeier Hansson said this on page 261, "Learn to cope with the panic attacks of unexplained errors."

To create a new, struct-like class, use "Rating =, :rating)".

ActiveSupport adds a ton of useful methods to the String class that alleviate some of the pain associated with Ruby strings. (I like the way Python treats characters and string slices a bit better.) For instance, it adds .from and .to for slicing.

Use "config.active_record.sch…