Sucker

It's official: I'm a sucker. I got an iPod for my birthday two months ago. And I love(d) it. I've become addicted to a handful of podcasts over the past few months and my collection of music has been slowly growing. My car radio has largely forgotten the sound of traditional broadcast radio.
Media_httpstaticflick_utfcc
Yesterday, my iPod booted up with this icon. I took it back to Best Buy to get it exchanged, only to find out the extra fifty bucks spent on "extended service" or whatever they called it means they ship the iPod back to Apple for repair instead of making me do it. Whoopti-freaking-do. No exchange, no loaner. Three weeks without my beloved MP3 player. Secondly, two months then it breaks!? What's up with that? This can't be typical. I hope not. Especially if I only get to enjoy music and podcasts for a couple months at a time with three-week intermissions. Update: After two and a half weeks, I called Best Buy to get an update. Their response: oh yeah, we were supposed to call you; you can come get a new iPod now. That's weird.

Junk Email Filter Dot Com

We just started using an email filtering service at Cedar Ridge. So far, I'm very pleased with it. In the two days it's been in place, only a handful of spam messages have passed through to our server, and every one of those were filtered by our existing DNS blacklist filtering. The filter works by proxy, meaning all mail destined for our domain is first delivered to junkemailfilter.com. Their server filters out the spam using some fancy voodoo and delivers the good stuff to our server. Very simple, and no configuration needed or software to be installed on our end. These filtering services seem to be getting more popular, or maybe it's just that I'm noticing more of them. The cool thing is that the junk mail never touches our server, so the server load is lightened considerably. I'd guess our mail server will be doing about 25% of the work it used to. That saves us bandwidth, processor load, and generally makes our staff much happier.

Less Spam

I have an ongoing experiment in which I never empty my Spam folder in Gmail. On the left side of the screen, when I log in, I can see how many spam messages I have. Gmail automatically deletes spam messages over thirty days old, so this is an accurate representation of how many spam messages I get in a given thirty-day period.
Media_httpstaticflick_qopgf
When I first started using Gmail, my spam folder grew quickly to contain over five hundred spam messages! But over the last several months, my spam count has slowly dwindled to 150. Why? I can't pinpoint the reason other than maybe spammers are concluding it's less effective than it used to be. I mean, just about everybody heavily filters their email these days; the liklihood of a spam message getting through to most inboxes is dismal I think. Is this the beginning of the end? Have we reached and passed the spike in spam history? Not that I think spam will ever completely go away, but it's possible it's declining a bit and will level off at some bearable point. What about you? Have you noticed less or more spam in your email? Update 08/02/2006: My spam count has grown to nearly 250 over the last month and a half. I guess it was a fluke. Update 12/12/2006: My spam count is now over 1000! So much for my less spam theory.
Media_httpstaticflick_jjtia

Python Rehab Clinic, Part I

I don't know how many people are switching from Python to Ruby these days, but I've learned a bit and thought it would be helpful to a few people if I cross-referenced my Python knowledge to my (growing) Ruby knowledge. I got this idea from James on the OK.rb mailing list. Part One will focus on where to find what in the Ruby community. With any programming language or framework, you have a set of resources you go to often to find what you're looking for. I had a list of Python-related bookmarks I frequented; now I have a list of bookmarks for Ruby stuff. One disclaimer: this is not a comprehensive list or comparison. It is just a representation of my Python world cross-referenced with my Ruby world. Language Reference Standard Library: Python - Ruby Built-in Classes: Python - Ruby Interacting Shell: python - irb File Extensions Standard: .py - .rb Console-less: .pyw - .rbw Compiled/Bytecode: .pyc, .pyo - none Web Frameworks Beastly: Zope - none MVC: Django, TurboGears - Ruby on Rails Lite: Quixote, CherryPy - Camping Content Management Systems Plone - Radiant Object-Relational Mapping SQLObject - ActiveRecord In the spirit of Release Early - Release Often, I'm posting this in the hopes I will think of stuff to add to it later.

Ten Rails Tips

Here's my Ten Rails Tips, expanded a bit to try to explain my thinking...
  1. Scaffolding won't write your app for you, otherwise DHH would have called it "foundationing". Too often I see people addicted to the Rails scaffolding feature. I've found that it's often a crutch for actually thinking about the problem at hand. Scaffolding is great for a one-table model, but breaks down quickly when you have has_manys and other such relationships.I almost wish the Rails screencasts didn't include the demonstration of this feature, because it makes people think that's how you really start a Rails app. In reality, I rarely use scaffolding.
  2. Find inefficiencies using the development log. There's good stuff in there! Much of the time, looking through the log is unnecessary simply because Rails gives you such descriptive and pretty error messages inside the browser. But seeing the SQL being executed is invaluable for finding where your app needs to improve on the ActiveRecord side of things.
  3. Use :include where possible to minimize the number of db queries. This is where the dev log comes in handy; it will point out places in your code where you probably should have used Eager Loading (:include => :whatever). Seeing the (mostly) same SQL query repeated over and over again is good motivation for using this handy feature. When used correctly, multiple queries are combined into one, thus reducing the overhead of communicating with the database.
  4. Learn SQL, including joins; it will help you to make your queries more efficient. You can probably go your whole life without ever learning a drop of SQL (thanks to ActiveRecord), but I would recommend getting a decent grasp of it, because the fact is, it's still handy to know what the heck is going on. I've found that ActiveRecord isn't the silver bullet for ridding the world of SQL forver. Instead, it simply makes the mundane stuff a lot funner.
  5. Learn to "feel" the presence of helpers and shortcuts -- chances are, if you think there should be one, there probably is one. Few things are more irritating than writing a bunch of code and then finding a one-liner in the Rails API docs that does the same thing, especially when it does it better! Turns out, you can start to get pretty good at "feeling" the existence of such things. When writing stuff that seems redundant, think to yourself, is this a task specific to my application, or is everyone dealing with this? If the latter, then there's probably a helper/shortcut/whatever to do it for you. Don't waste lines of code on stupid stuff.
  6. Create models to handle your data. Models aren't just database tables. Rails doesn't care if your models are ActiveRecord or not. Create models to do your heavy lifting. If you find yourself writing more than a few lines in a controller method, ask yourself, is this something the model could be doing itself? If yes, move it to the model. It's easier to work with models on the console than controllers and views.
  7. Write a plugin if you think you'll ever use the code in another app or across different controllers and models. Don't repeat yourself. If you need the same bit of code again, put it in a plugin so it's available all over your app. Then, it's also easy to reuse that code in your next app.Creating a plugin is as easy as "script/generate plugin my_plugin".
  8. Learn to use the console. Try out complex code there before you put it in your app. "script/console" is a command line for your Rails app. Use it. Learn to live in it.
  9. Instead of just "testing your app," write "tests for your app." Grep (or "tail -f" rather) your brain for the word "test". When you think I should test that. Don't! Write a test to do it instead... then run the test. It only takes a tiny bit more time, then you get the added bonus of being able to run all your tests again later.
  10. Keep http://api.rubyonrails.com in a Firefox tab and turn on "begin finding when you begin typing." I live in the API docs. Firefox has a nifty feature that makes finding stuff in the docs much easier... just start typing! Need to know what arguments the render method takes? Type render and hit enter!