NOLA Bound

Tomorrow I get to hop on a plane with several coworkers (and even more acquaintances) and head to RubyConf in New Orleans. This is very exciting for me, because although my mother took me there more than a couple times when I was small, I have no memory of having ever been to New Orleans. I'm very happy to be remedying this omission in my Stateside travels.

Best yet: because I am an excellent husband, I'm staying in New Orleans a couple extra days beyond the conference so that The Wife can come out on Saturday to join me for some of those famous "good times".

Laissez les bons temps rouler!

Depending on how things go, I might actually report back with details of what we ate and what we drank and what we saw. Or maybe not.


I'm up way too late tonight (considering I woke up at 4:45am today) because I'm totally psyched for the mountain.rb Ruby conference that gets started tomorrow evening in Boulder. It's really exciting to have a conference of this caliber right here on my home turf. I'm sure I'll post more about it later, but if it's your thing, you might want to follow the #mountainrb hashtag on Twitter as well as this Twitter list of attendees, speakers and sponsors I've tried to build.

My various social network feeds are bound to be pretty single-focus for the next few days, so fair warning. ;)

Developer Day, Boulder

Last Saturday I had the pleasure of hanging out for a full day with a bunch of geeks in the TechStars space in downtown Boulder for Developer Day. The event was hosted adeptly by Ben Scofield of Viget Labs and featured a rather enjoyable variety of presentations. Overall, the content was good and the folks I interacted with were all good people. The only downside was the TechStars office had the heat cranked to sauna levels -- I pitted out both the t-shirt I wore that morning *and* the conference t-shirt, which I switched to after lunch. Developer Day Boulder

The majority of the crowd were Ruby/Rails developers, but there were a few Pythonistas, Scala fans, Apple/iPhone Objective C hackers, and even one C++ programmer. One of the attendees was actually a former co-worker from the Data Slaughterhouse days. It was nice to see a familiar face.

Other noteworthy trends:

  • MacBook Pros were almost ubiquitous.
  • iPhones were almost as common, though a few guys were proud of their mobile phones that are actually primarily phones.
  • No big surprise, it was a total sausage-fest. There was one woman in attendance. One.

I'll give some of my notes from the presentations after the jump, so feel free to move along if that's not your thing.

Chad Fowler -- The Passionate Programmer

This talk is based on Chad's book of the same name and was a hell of a way to get things started. Chad offered up some great inspiration. Some notes:

  • Having a plan (even one that turns out to be wrong) will make things seem easier.
  • Don't just say "I've always wanted to ..." Go out and do it!
  • Innate talent (or the belief that you have it) can make you lazy. Practice makes you better.
  • The easiest way to market yourself is to be remarkable. Let others sell you.
  • Another way to market yourself is to be a guide. People talk about the guy that teaches them something.
  • "I am a ..." can be dangerous. Don't pigeon-hole yourself

Chris Perkins -- TurboGears: An Exercise in Natural Selection

TuboGears is a Python MVC web framework. Chris told us about the evolution of the framework. The TG team is always striving for the best in class tools, which means they have switched the libraries they've used for ORM, web server, templating engines, and front-end scripting. This makes TG incredibly flexible, but my reaction was that it was a bit too flexible. It's an impressive framework, but it struck me a bit chaotic.

Rob Sanheim -- The Cloud - Real World Applications and Pragmatics

Rob showed us some awesome real world uses for the Amazon Elastic Compute Cloud (Amazon EC2). After making the point that "software as a service" (like GMail, etc.) is not the same as cloud computing, he showed us some really cool projects he's working on. First was run>code>run, a continuous integration service that integrates with GitHub. Then he used a new project called braincron, a natural language reminder application, to demonstrate setting up a new EC2 node with automated configuration using Chef Solo. Pretty impressive stuff, most of which was over my head -- I'll have to change that!

Jeremy Hinegardner -- Playing Nicely with Others

Jeremy's presentation was all about how we as developers always use more than one language in a project. For example, I use Ruby, T-SQL, JavaScript, and some amount of HTML + CSS in every project I work on. This reinforced Chad Fowler's point that telling someone "I am a Rails developer" is kind of silly (although using the framework might imply the multiplicity). Jeremy covered some commonalities of programming languages and application tools: data structures, communication, persistence. He then covered some interesting new tools that are available right now, such as: Tokyo Cabinet, Tokyo Tyrant, Redis, Beanstalkd, and MongoDB. MongoDB actually got a lot of love during the day -- something to look into.

After Jeremy's talk we broke for lunch, which was then followed by a handful of "lightning" talks -- five minute presentations:

  • David Eisinger gave an overlapping intro to Ruby and Mid-90s Hip Hop which featured lots of fun using the "say" command in Mac OS X.
  • Jason Turner showed off ChaiScript, a C++ scripting language.
  • Ben Reubenstein suggested we think about donating our time to good causes in order to expand out skillset productively.
  • Bobby Wilson ranted a bit against templating systems in Rails.
  • Jess Martin gave a passionate overview of "The One True Way of CSS", with which I completely agreed.
  • Ben Scofield talked a lot about how convoluted comics books and the comics publishing industry is and a little bit about how a relational database might not be the best way to model them.

David Eisinger -- Email Interfaces for Your Ruby Apps

David is another member of the Viget crew. He started his presentation with a sort of philosophical discussion of email interfaces to web apps: why they are a good idea, hurdles to overcome, things to be careful of, good examples from the real world (people mentioned several times). He definitely opened my eyes to the idea of using email, which even your Nana knows how to use, as an interface to an application. The latter half of the talk was left to briefly covering all of the technical aspects of an email interface, from the mail server, the software you use to fetch the mail, and finally how you process the email messages. Not a ton of details, but a great topic.

Derek Chen-Becker -- Stepping Up: A Brief Intro to Scala

I must confess that before this presentation, I had moved to the back of the room to find a power outlet for my laptop, so I really didn't give my full attention. Even given that, I have to say Scala is pretty interesting. It compiles to 100% Java bytecode and is sometimes even "better" than compiled Java. I've never learned Java -- static typing honestly makes me itchy. Scala feels a lot more like a dynamic scripting language and seems more approachable to a monkey like me. It's not the prettiest code I've eer seen, but it's interesting enough that it's on my radar now.

Bill Dudney -- Core Animation on the iPhone and Mac

Bill "wrote the book" on iPhone development. I was mostly excited for his talk just to get a little exposure to Objective C, and ... wow. In the words of the day's final keynote speaker, Bruce Eckel, "I don't know what the square brackets do. I see there are a lot of them..." Getting past that, Bill made great points about using animation in iPhone apps to make the user experience more "real". He also showed us how the core animation libraries handle a lot of the heavy lifting of animation for you. Pretty neat stuff.

Bruce Eckel -- The Archaeology of Language Features in C++, Java and Python

Talk about writing the book! Bruce wrote what many folks consider seminal tomes for both C++ and Java. He's over that, now, though. These days Bruce loves his Python. (Incidentally, he likes Flex for UIs.) His presentation covered some of the decisions that negative affected those older, static languages - in particular the mandate for backward compatibility. As counter examples, he mentioned that both Python and Ruby have recently undergone major overhauls that have changed or dropped functionality entirely. The big pull-quote from Bruce's talk, though, was his feeling that with the help of new players like Scala, Java is fast approaching "legacy" status. I'm cool with that.

And that was that. I bailed on the after-conference beers, opting for the company of my darling wife instead, but I really enjoyed Developer Day. If it comes to your town, definitely go.

BTW: In many cases, if you go to the blogs of the speakers linked above, you'll find their write-ups of the day, too. Always an interesting exercise to see how others see events...

Quick Hits

  • My Colorado Avalanche managed to make it through the first round of the NHL playoffs. Now they have the pleasure of playing the possibly unstoppable Detroit Red Wings in the second round. In truth the Wings have looked fairly human this season, especially in the playoffs. We shall see.
  • The Wife and I are suddenly both able to jog something like 2.5 miles continuously. This is a big jump from where we were. I definitely believe a course change is the prime contributor to the improvement.
  • Since September of 2007, I've manage to whittle myself from around 220lbs to 190-ish. I only have this to say: It's a lot of friggin' work.
  • I cannot tell you how excited I am about GTA IV. The multiplayer action looks like a flat out hoot. Email me if you want my Xbox Live gamer tag. ;)
  • Meanwhile, The Wife is all about the Karaoke Revolution on the 360. They've been all over adding downloadable songs to it. It's really pretty impressive so far. Not to mention tons of fun.
  • I'm really sick of the Democratic primary garbage. I'm still backing the liberal black man, though.
  • My Ma has a fancy new deck on her house. It's totally sweet.
  • I really need to sand & stain my deck this year (just like I have for the past couple years). Boo.
  • Went to a DeRailed (the Denver Rails user group) meeting last night. They covered interesting material, but I ended up leaving early anyway. It was definitely what you'd expect, demographically. ;)

RoR: acts_as_solr Highlighting

This post is pure geekery, so never you mind if that's not your thing... We use a Ruby on Rails plugin called acts_as_solr for full text search on some of our Rails apps at work. This provides an interface to a Solr search engine, which is based on Lucene technology. Lately I've been digging into some of the more advanced features Solr provides, for which I found this QuarkRuby post invaluable.

You'll notice I posted a somewhat confused comment recently. I've been trying to post a follow-up comment to share what I've discovered on the topic, but it's not letting me for some reason, so here it is for the sake of teh intarwebs:

Just to follow up: It turns out AAS doesn't (yet) support some of the hl parameters, including requireFieldMatch.

FYI, though, requireFieldMatch will only return highlights if you searched the highlight fields specifically, so q=(test)+AND+type_t:Post&hl=true \ &hl.fl=body_t,title_t&hl.requireFieldMatch=true will not work, but q=(body_t:test+OR+title_t:test)+AND+type_t:Post \ &hl=true&hl.fl=body_t,title_t&hl.requireFieldMatch=true will return the expected highlights.

In my eyes, that makes that feature kind of "meh"...

Also worth noting, I submitted a patch for rebuild_solr_index. It was ignoring the :if when batch_size was supplied.

I'm kind of excited about the patch. It's totally trivial and perhaps not even the best implementation, but it's my first contribution to an open source project. That's totally cool in the geekiest way possible!

Prairie Doggin'

There's plenty going on these days, but that's all I can think of to share at the moment.


A common need for web apps is to insert something into a database table and then immediately find out which ID got assigned to your new thing so that you can refer to it later in the script (probably while inserting more data). A lot of folks start out doing something along the lines of:

INSERT INTO Addresses (address, city, state, postalcode) VALUES ('123 Main St.','Springfield','MA','01109'); SELECT max(id) as ID FROM Addresses;

After that, the folks on Microsoft SQL Server tend to discover the combination of SET NOCOUNT ON and @@IDENTITY:

SET NOCOUNT ON; INSERT INTO Addresses (address, city, state, postalcode) VALUES ('123 Main St.','Springfield','MA','01109'); SELECT id = @@IDENTITY; SET NOCOUNT OFF;

Now, at my new gig, we use PostgreSQL. Today, I finally found myself wondering if/how I could achieve the NOCOUNT/@@IDENTITY behavior. Turns out, it's super easy and almost even sexy (since version 8.2, I guess):

INSERT INTO Addresses (address, city, state, postalcode) VALUES ('123 Main St.','Springfield','MA','01109') RETURNING id;

That, my friends, is HOTT.

Sure, it's non-standard SQL, but what's the point of picking a particular RDMS if you don't use the magic that it offers?

Birds Flying High, You Know How I Feel

Near the end of August in 2001, after a four month period of being unemployed, I finally found a job with a Boulder company called (Holy internet cliche overload!). We'll round the ensuing passage of time up to five and a half years for the purpose of this discussion. In that period the company changed it's name to InsightAmerica, moved its office to Broomfield, and eventually was acquired by a corporate giant (name uselessly withheld). The basic "job" of the company never really changed, and the work was mostly interesting on a nuts-and-bolts level (I still think we regularly pushed ColdFusion well beyond its normal bounds and managed to make it work.), even if the bigger picture at times gave me the heebee-jeebees.

At a more micro level, I've had the opportunity to work with some amazing people (particularly within the technology teams - but outside that, as well). In fact, most of the people I currently consider my best friends were first coworkers.

On a work level, there have certainly been ups and downs, but on a personal level this job has been nothing but positive.

You've probably already guessed that I've decided it's time for me to move on.

  • I'm going back to Boulder. (meh. I'll miss my 10 minute commute, but I only think I'm doubling it.)
  • It's a very small company. (sweet! I enjoy the dynamic of a small company much more than a megalocorp.)
  • I'll be working with an old friend. (yay! This is actually the only reason I applied for the job when I saw it come across the wire.)
  • I'm going to be working daily on a Mac. (w00t! This excites me unreasonably. Not to mention the HUGE monitors they use.)
  • I'll eventually get to work with Ruby on Rails professionally. (double w00t!! I've been a fanboy since the early days, though I've never actually done anything with it.)

I'm also leaving a lot of friends behind. Hopefully I'll be able to keep in touch - the Denver Metro area isn't a very big place, really. Some of us already have outside-of-work connections, but I want to cultivate more of those.

So, yeah... That's what's going on with me.

Let's have Nina Simone carry us out, shall we?

Its a new dawn Its a new day Its a new life For me And I'm feeling good Plan of Action

I've actually be having a lot of fun thinking about this and getting ready to move into planning and design. First and foremost, I'm going to use this as a learning exercise to teach myself some new technology, so don't expect a very rapid turn around. I figure I'll either build the site using Ruby on Rails or Django, so that'll be cool. I think I have the option of using PostreSQL on the backend, so I might do that, as well. (Not that I expect this to be a big test of a database...)

As for features, I think we want the following for submissions: tagging, commenting, searching, ranking, and maybe a "favorites" pool (favorites could work as a binary ranking system... the more a submission is "favorited", the more popular it is...). Ideally there would be an RSS/Atom feed for the latest submissions.

Users need profiles with optional links to blogs, Flickr accounts, MySpace pages, etc.. They could also have some semi-social functionality like "buddies", and so forth.

Hopefully we can run out some t-shirts/stickers/whatev from the best submissions. There's some vague potential for some actual goods, but that's nowhere near reality at this point.

What else do we want/need?

Paging Oracle Results

At my workplace, we often like to page through query results. That is, we'd like to show results in bunches of, say, 50. Some databases (none that we use: PostgreSQL and MySQL) do this using LIMIT and OFFSET: select * from table where blah = 2 order by thing1, thing2 limit 50 offset 100 That query would give you the 3rd "page" of 50 results. (Note: I believe MySQL has shorthand: LIMIT 50,100)

I think Omnidex (a funky flat file indexing engine we use) lets us do something like: select top 50 skip 100 * from table where blah = 2 order by thing1, thing2

SQL server has the TOP, but I have no idea how to do offset/skip...

Anyway, what I do know is my boss kept bugging me to figure out how to do it in Oracle now that we are playing with a new database on that platform.

So, thanks to the internets, I present you with the wonderfully wacky world of paging in Oracle:

Select * from ( select t1.*, ROWNUM rn from ( select * from table where blah = 2 order by thing1, thing2 ) t1 ) where rn between 101 and 150

Key bits:

  • You have to alias the inner-most select if you want to select * (That's the "t1" jazz.)
  • ROWNUM is a calculated field. Each select has it's own rownum column under the covers. This the real reason there are so many nested "views" to do this. The first select has rownum values that are calculated BEFORE the "order by". The second select has rownum values that are calculated AFTER the "order by" in the inner-most select -- this is the rownum set we actually want to filter, so we include it in the select (with an alias). The outer-most select is needed to actually apply that filter.

Caveat: My friendly neighborhood Oracle DBA tells me, "Rownum is virtual, you aren't guaranteed that 101 through 150 are the same every time."

Alternative: Said friendly neighborhood Oracle DBA came back with another method that I have yet to play with seems to work nicely:

Lets go this route, subtle difference, but there is a reason.

Select * from ( Select a.*, rownum rnum From ( select * from table where blah = 2 order by thing1, thing2 ) a where rownum <= 150 ) where rnum >= 101

It has to do with the way Oracle processes the COUNT(STOPKEY). Also I had to remember that in 8.1 that stuff wouldn't work. With 9i and above we should be good to go.

MacGyver to the Rescue

So get this: That problem I had with ColdFusion 5 and Oracle9? Well, at this point the work around may be what we call a "gateway" solution. That means we have CF5 post search parameters via HTTP (using the CFHTTP tag) to a ColdFusion MX 7 server, which actually does the search on the Oracle database (MX and Oracle like each other fine). The CFMX code then takes the resultsets from the Oracle reference cursor and outputs them as WDDX XML. So, that WDDX gets deserialized on the CF5 box and voila! the CF5 box has its data to play with.

Unreal. Don't worry, this sort of gymnastics is just as ridiculous as you think it is (almost as ridiculous as the fact we're still using CF5). The thing is, it's likely to end up in production...

Jake Sutton: MIA

So, yeah... I'm still here. Here's a little catch-up:

  • My efforts at work on the superultramegaubercrazy-high priority project have come to a rather frustrating result so far thanks to interoperability problems between ColdFusion 5 and Oracle9. Every time we hit the Oracle9 database it causes the memory usage of the ColdFusion server to climb, with that memory never being released. This eventually causes the connection to the database to die with an S1001 Memory Allocation Error, which requires a ColdFusion restart to fix the problem (until the memory allocation builds back up again). Super-fucking-duper.
  • The Big Blue Couches rock. While we are trying to keep the pets off them, it's obviously futile. At least the puddles of Mingus hair come off the ultra-luscious blue microsuede without a problem. I'm just extra-pleased with the fact taht I can lie completely prostrate on the big sofa without touching either arm.
  • The Wife and I have been to the hotbox yoga a total of three times so far. I am enjoying it quite a bit, though I think I may have overstretched my back the last time out. We hope to squeeze a couple more classes into our two week trial period.
  • My motorcycle wrenching buddy Erik and his wife are inches away from having their baby boy. Very exciting times for them!
  • I'll be brining the second turkey of the month for Thanksgiving festivities starting tonight. If you haven't brined a turkey or at least eaten the product of said process, I can't even express how much you need to try it.
  • I'm almost done with the Tales of the Otori trilogy. I highly recommend all three books.
  • Now let's turn the lens outward a bit:

And thus concludes today's category smorgasbord.