I built a stupid app this weekend. In doing so, I tried out a bunch of technologies that have been around for a while, but are new to me.
They are:
Here’s my review of each.
I don’t really like coffescript. I will never be a fan of languages that are whitespace sensitive. But I still use them. I’m willing to overlook the straight-jacket of whitespace sensitivity as long as the laugage is good enough. Now that I think about it, both haml and sass (also used this weekend) are whitespace sensitive, and also compile to a base language before being transmitted. Their benefits are worth it, but they’re not on trial today.
I like the initial idea of the @ operator in Coffeescript. It’s a shorthand for “this.” And you’d better remember that. It can’t be used like you would use it in ruby. I was stuck for longer than I’d like to admit wondering why my assignment to an instance variable wasn’t working in one of my callbacks. Culrpit: @ did not reference my class, but the context that I was currently in. From a javascript perspective, that behavior is obvious. From the object-oriented, ruby-like context that Coffeescript was trying to pretend I’m working in, it was baffling. I had to fall back to the that = this idiom in order to get my callbacks to close over the object I really wanted to operate on.
The documentation is pretty abysmal too. You’re lucky if you get more than a couple of examples. The tutorial doesn’t even show how to make multi-line functions! Nor does it demonstrate how to use an in-line function for a function parameter that is not the final parameter. The whitespace-sensitivity can make it a bit confusing.
Only from knowing javascript did I know that I would have to call a co-member function with @ or this. Somehow in their discussion of classes in both the tutorial and the book, they managed to avoid calling a method from another method. I’m not asking for a python style formal grammar documentation, but there’s a lot to be desired here.
Coffeescript also makes it really hard to write library files. They’ve gone from javascript’s implicit globals to the complete opposite, which is not allowing any globals at all. This is an improvement in many ways, but means you have to fall back to raw javascript or settle with using the window global if you want to actually expose your code to something outside the current file.
I had my code set up with separate responsibilities: a library that interacts with the twitter API, and a UI frontend. These files can’t talk to each other at all without globals. It’s a shame that the architecture of Javascript has forced that behaviour, but coffeescript goes and makes it worse. I had to use the following code to create a global and then drop my class into it:
`TweetMax = {}`
class TweetMax.Twitterer
If it’s not clear, the backticks drop me down to raw javascript. Thankfully I can at least do this, but this is like having to drop down from C to assembly if C didn’t have the extern keyword.
The majority of my interaction with jQuery Deferred objects was just to use the bindings off of ajax actions. However, I did write a few custom ones of my own. It’s a great API, and is probably a pattern that I’ll wonder how I ever lived without.
The one deficiency that I noted, is that you can’t reset the status of a deferred object. Once a deferred object is resolved, it can’t ever be re-resolved. This meant that I had to pull in a proper eventing framework instead of just re-resolving the deferred that I was supplying to the clients of the library. Not a big deal, and for many uses cases, that’s probably a deliberate feature. But for me, it was a deficiency.
The twitter API itself is nice. It’s available in a variety of formats, and is quite sensible about urls, parameterization, and paging.
It all falls down in the service. Throughout the weekend I was constantly plagued with 502s (Service Unavailable). At first, I thought I might be getting rate-limited, since my app does require quite a few sequential requests. After a bit of googling and head-scratching, I discovered that the API service is simply flaky and goes down all the time. 502s aren’t really an exceptional failure with the Twitter API. It means “try again in a few seconds”. When working with the twitter API, you absolutely must write code that anticipates that the servers will be constantly failing to fulfill your requests. Which is okay in theory, but leads us into the next technology…
JSONP is a way to get around the cross-domain restriction on XHR requests. This means my clients can make requests directly to the Twitter API without having to filter through my server first. The specific implementation of the format isn’t entirely important, but how it interacts with the browser is. The browser loads the response from a JSONP request the same way it loads any other resource. Basically, to do a JSONP request, you add a script tag to the DOM, the browser fulfills a request, and a function gets called when it all works. What happens when it doesn’t work? Nothing. The only way to figure out that request failed is to set a timeout in Javascript that fires if your function doesn’t get called within an arbitrary time limit. Ouch. So that twitter API that is constantly failing? Doesn’t play very nice with JSONP. Even with the timeout, you don’t get the luxury of knowing what exactly went wrong. So I have to jump through more hoops to tell if I’ve been rate-limited, or if Twitter is just screwing up again.
My coworkers finally managed to convince me to switch to vim. What a chore. I basically spent an entire weekend customizing someone else’s .vim directory to my tastes, which was mercifully easier than tracking down the plugins and configuring them myself, but it was a frustrating bit of changing my vimrc from within a vim that is not quite configured the way I want it.
It’s a real shame that the vim authors grew up in an era before video games. In my humble opinion ijkl (used in the same way as wasd) is a vastly superior directional scheme to hjkl. It’s directionally intuitive, unlike the linear hjkl, which relies on memorization. It also keeps your index finger on j, where it belongs on the home row. I use h for insert. It’s not as crazy as it sounds. How often do you repeat ‘go left’? Sometimes. How often do you repeat ‘insert’? Never. Because now you’re in insert mode. Stretching to h for repeated go-lefts became uncomfortable, and sometimes I would unconciously move my whole hand to start on h, which would offset my right handed typing and I’d have to find my place on the home row again after moving around.
So far I haven’t run into much trouble. At least vim has the configurability to change this sort of stuff, even if it does take me an entire weekend to get everything sorted out. Thanks go to Deewiant for this comment, which helped me get my bindings consitent.
Here’s the rebindings, for anyone who wants to join my little cult:
noremap i k
noremap I K
noremap <C-w>i <C-w>k
noremap <C-w>I <C-w>K
noremap <C-w><C-i> <C-w><C-k>
noremap j h
noremap J H
noremap <C-w>j <C-w>h
noremap <C-w>J <C-w>H
noremap <C-w><C-j> <C-w><C-h>
noremap k j
noremap K J
noremap <C-w>k <C-w>j
noremap <C-w>K <C-w>J
noremap <C-w><C-k> <C-w><C-k>
noremap h i
Availability of “Starship Troopers” by Heinlein:
1. Kindle Store: 0
2. Google search for “starship troopers mobi”: First Link
You lost a sale!
Okay, so it’s done. As done as it’s going to be, anyway. I really can’t be bothered to spend time beautifying a dirty hack of a web scraper. You’ll have to know about ruby and have a gomtv.net login with a season ticket in order for it to work.
Here it is:
https://github.com/Lugghawk/SCScraper
Enjoy.
I finally got around to some stuff I’ve been meaning to do for a while this weekend/holiday.
I’ve recently been using mediastreamer to stream my music to work. The actual audio playback portion of mediastreamer relies on either flash or the HTML5
Anyway, about half my collection is in FLAC. Even if the endpoint did support FLAC playback, it would be too large to be practical for all-day-streaming. Since I didn’t want to go to the bother of reencoding my entire collection just so I could stream it over the internet, I sat down this weekend and started hacking transcoding support into mediastreamer.
The tag reading library used by mediastreamer already supported FLAC, so adding FLAC files to the database was as simple as updating the glob that searched for files. My approach to transcoding was to use commandline tools to decode and reencode the file in question, and then pipe that into the webserver for streaming. It turns out that everyone’s implementation is broken in some way unless I specify a Content-length header. As far as Flash is concerned, files hosted without a Content-length never end, meaning the playlist never advances. Chrome’s native
There’s two ways I can think of to know the file-size, so that I can set the Content-length header in HTTP:
Method 2 is currently in development. Deterministic output means that VBR is right out, so I’m stuck with encoding to CBR mp3. I’m estimating the Content-length by multiplying the length of the song in milliseconds by (bitrate / 1000). This is close enough, but somehow results in a length several kbytes longer than the output from lame. Interestingly, this doesn’t seem to affect Flash; the Content-length doesn’t need to be right, it just needs to be close. How frustrating. Still, it would be nice to know how to accurately predict the output of lame. It’s unsettling to be setting incorrect Content-lengths.
I’m going to look into submitting bug reports to webkit for their poor <audio> support. Or maybe not. It’s possible that Sinatra is just incorrectly responding to Range requests, which webkit seems to like - but range is probably a dangerous proposition for a file that’s being dynamically generated, so I’m not entirely sure whose fault it is. No other browsers use Range when they make requests for their <audio> tags, as far as I can tell. Unfortunately, I’ll probably have to build a webserver that hosts both vorbis and mp3, without Content-length headers, to test this across a wide range of browsers.
Another bugfix release. Looks like I forgot to set ConceptRoll for turrets (because apparently you want to roll vehicles). Not being able to move turrets left and right should be fixed. If your config files are in a non-working state, simply open the program and hit save for a fix.
NOTICE: Alpha 2 is bugged. Please get Alpha 3. Download Browse Source Alpha 2 is out already, with fixes:
NOTICE: Alpha 1 is bugged (big surprise). Please get Alpha 3.
This is the first release of the BFBC2ConfigTool. I’ve hacked up a quick alpha version that should painlessly deactivate mouse smoothing, and allow people to fiddle with their sensitivities. There’s also an option to make the Russians in BFBC2 speak in English, since apparently some people were encountering problems with that.
This initial alpha release is targeted mainly at reddit users. If all goes well, I’ll post about this on the EA forums.
This is alpha software. It will probably break. Use at your own risk. There is currently no input validation. I take responsibility for nothing. Please report bugs so I can fix them.
To use, simply run the provided exe. You need .NET 2.0.
As noted by a reddit post, reddit doesn’t accept bfbc2:// style links. It’s probably going to be a fairly common problem. I wrote a proof of concept script that just does a simple 302 redirect from http to bfbc2. The base URI is http://fitzsimmons.ca/bfbc2/[server string here]. You can enter a server string raw, or URLified (with bfbc2:// on the front) and the webserver will automatically redirect you to a URI that the handler can pick up.
Here’s a couple examples:
http://fitzsimmons.ca/bfbc2/2503473115,3fc5640a-7dbb-415f-9e45-ba6cec0562dc,A Bacon Server
http://fitzsimmons.ca/bfbc2/bfbc2://3363010643,b652b484-4188-42ea-8885-50fc4991af5b,Reddit%20Unofficial%20Gaming%20Community-%20Chicago
This should allow you to link from places that only allow http style URIs. If this takes off at all, I’ll write a some info about what’s happening on the redirect page, for people that don’t have the handler set up.