Thursday, February 28, 2008

Paul Graham Saw 2008 In 2001

We never had enough bugs at any one time to bother with a formal bug-tracking system.

TDD: Great Minds Think Alike

Patrick Kua

Jay Fields

Giles Bowkett

How To Understand Software Development Management

The director of PowerPC software was an academic on leave from Dartmouth. The director of PowerPC marketing was the son of a math teacher. Seeing the value of putting this educational software on every Macintosh in every school, they promptly adopted us.

Then things got really weird. The QA manager assigned people to test our product. (I didn't tell him that those people were already working on it.) The localization group assigned people to translate it into twenty languages. The human interface group ran a formal usability study. I was at the center of a whirlwind of activity. Nevertheless, Greg and I still had to sneak into the building. The people in charge of the PowerPC project, upon which the company's future depended, couldn't get us badges without a purchase order. They couldn't get a purchase order without a signed contract. They couldn't get a contract without approval from Legal, and if Legal heard the truth, we'd be escorted out of the building.


The Graphing Calculator Story

Wednesday, February 27, 2008

Never Complain. Only Ever Code.

That way you can avoid idiots who think they're entitled to tell you their opinion on debuggers.

Learn from me. I learned this lesson the hard way - by listening to tons of people telling me their opinion on debuggers. By the law of averages alone I can guarantee for a fact that at least some of these people were idiots.

But blogging this was a mistake, or at least, blogging it with comments enabled was a mistake. Blogging mistakes are very easy to make. Avdi Grimm recently made a good point in a self-defeating way and pissed some people off in the process. But the people who are angry need to chill.

"Metaprogramming" is a new thing for many people, a shiny magic hammer that turns everything around it into a nail, and the results can be silly bugs. I've seen gems with "clever" uses of method_missing trap errors from utterly unrelated code; I've seen Rails evaluate any and all code in my .irbrc and had Jeremy Kemper from Rails core angrily telling me that this was not a bug. We do need to evolve norms like the Emacs system Avdi describes:

I look at the Emacs community as an inspiration. Emacs, as many of you probably know, is essentially just a lisp machine. Emacs Lisp, the language it is written in, is every bit as dynamic as Ruby. Functions can be replaced at any time, by code in any package. And because all Emacs Lisp code is intended to extend the Emacs editor, it is not uncommon for hundreds of different Emacs Lisp packages to be running in the same process, all coexisting and interacting. And yet, for the most part this melting pot of extensions all function together smoothly and without breakage.

Why? I think the biggest reason is community conventions. I’ve read a lot of ELisp code, and I have very rarely seen the equivalent of Ruby-style monkey patching. Even the advice mechanism, an AOP-like feature which enables functions to be dynamically wrapped and chained, somewhat like Rails’ alias_method_chain, is used sparingly. Instead, every mature Emacs extension exposes a plethora of “hooks”, extension points that other packages can attach their own handlers to. Other packages add their handlers to these hooks, and to hooks that the core Emacs code provides, and thus they cooperate largely without collisions.


Although it's dangerous to look at the Emacs community as inspiration, Ruby will obviously have to evolve some set of norms. Convention over configuration is also about conventions over confusion.

But what Avdi's saying is presented unwisely, as a complaint, and makes the first person to present any solution become the hero with the solution.

That hero is Pat Maddox.

There's a crazy idea out there that monkey-patching is bad. alias_method_chain is perhaps the worst offender. It allows you to easily decorate an object with behavior at runtime. The problem occurs when maintaining code that is all alias_method_chain'ed out - such as ActiveRecord::Base and the gazillion plugins that monkey patch it. It's tough to figure out what method you're actually aliasing away, and god help you if you rely on ordering.

Some may criticize, but I prefer to Do Cool Shit™.


Pat's solution is some cleverness around alias_method_chain and it's probably one of the only uses of "metaprogramming" you'll ever see which is truly meta. Pat runs alias_method_chain on alias_method_chain to introduce alias_method_chain logging.

Although this totally kicks ass, it's just a solution. It's not the solution. The solution will probably be some set of similar techniques - some group of different ways to Do Cool Shit™. This solution obviously deserves a place in that set of techniques, but since it only addresses one particular instance of the problem class Avdi identified, it only addresses that portion of the problem space. More techniques will arise over time. I guarantee it.

But for bloggers and programmers, the real moral of the story is: Always program first and blog second. Nobody will reward you, and the people who write the code that you correctly identified the need for will be like "booyah!" at you, even though in a sense it was really your idea. This puts everything on the wrong footing.

For instance, Pat's code uses globals. Any time a programmer brags about using globals, you know something fucked up is happening. Starting everything off with a complaint skews the whole conversation, and even the solutions end up tainted.

Also, poor blogging tactics can make you look like less of a programmer than you really are. For the record, Avdi contributed some wicked code to my Utility Belt gem recently which allows you to run Unix diff on any arbitrary pair of Ruby objects. (Wicked not in its complexity, but in the sheer lovely madness of the very idea.)

Never complain. Only ever code. Always program first and blog second.

Monday, February 25, 2008

code #7 ruby.reddit > opinions #1 programming.reddit

I've been #1 on the programming reddit a gazillion times with opinions.

People have been excited for me; I never cared.

This, on the other hand? This is cool.



A blog post consisting almost entirely of code reaches #7 on the Ruby reddit.

That rocks.

Why Americans Need To Pay More Attention To Politics

Ms. Simpson testified, under oath, to Congress about Karl Rove's involvement in politicizing the DOJ. What you may not know, however, is that her house mysteriously caught fire and she was run off the road in the weeks leading up to her testimony.

Sunday, February 24, 2008

Mindreader: Proof-Of-Concept Bayesian Rails App

Mindreader does simple favorite ranking and user prediction with Bayesian statistical AI.

This is not the same thing as a naive Bayesian classifier. A naive Bayesian classifier uses Bayes' theorem to classify text. Mindreader uses Bayes to chart a user's probable favorite topics, and then predict a user's probable identity from the topics they choose.

For more info:

http://rock-paper-scissors.googlecode.com/svn/trunk/doc/README_FOR_APP

To grab the code:

svn checkout \
http://rock-paper-scissors.googlecode.com/svn/trunk/ rock_paper_scissors

How To Dodge Corporate Monkeys

Many, many programmers have had or will have the experience of seeing somebody with more corporate-political power making a decision which is obviously wrong - where the obviousness is apparent only to anyone with any in-depth knowledge of technology.

For instance, you need to compete in a space where established best practices are agile, lightweight, swift, and battle-proven, with many successful examples - and instead of using the proven open-source solution with the proven agile strategy, management opts to build or buy something expensive, crappy, and stupid.

The easy solution in a situation like this: quit your job.

Easy solutions are great for Twitter, but this is a blog. Easy solutions are also great for teenagers, but this is for grownups, and grownups face tradeoffs. You could have a sick spouse, and need the health insurance; you could be in a small town, and face limited local options. You could even be otherwise very, very happy at your company, but faced with this one infuriating challenge.

The answer to your dillemma is very, very simple, but we're going to take the long way there.

First, we'll look at Google. Next, we'll look at Ruby on Rails. Then we'll look at Propellerhead Reason. All three of these highly successful technology projects have something in common.

After that, we're going to visit Ayn Rand, the L. Ron Hubbard of Libertarians, for some surprisingly useful advice.

Google

There's a lot to learn from Google - for instance, the Google guys go to Burning Man.



The Google guys are smart.

If you google Google for a while, you'll find a lot about simplicity. From its very early days, Google made simplicity a guiding principle. Google's sparse home page initially happened because neither Brin nor Page knew much HTML, but over the years it became a matter of pride, as well as a competitive advantage over busy, noisy, useless sites like Yahoo! and MSN.

In Google's early years, the company acquired a snooty, stand-offish reputation in the Valley, because companies that partnered with every one of Google's competitors to deliver content usually left Google's offices without a deal. Often they didn't even get a meeting. Google disdained these partner companies because they decided paying for third-party horoscopes and games was irrelevant to their goals as a company. Instead, Google targeted low-hanging fruit with superior technology. Today, they dominate their market.

Ruby on Rails

Ruby on Rails made simplicity a guiding principle as well - and not just a guiding principle but a war cry. David Hansson marketed Rails to the developer community with presentations mocking Java's complexity.



Hansson is also notorious for telling users to code something if they want Rails to have it, and to fuck off if they irritate him.



When people requested new features for Rails, Rails often refused to provide them. Rails is unusual in that one of the first things it did after it went 1.0 was remove unnecessary features.

As the Rails user base exploded, many people came to Rails, drawn by its phenomenal growth curve, with ideas of how it could be bigger and better; how it could become one size fits all. Other people came to Rails criticizing it, attacking it as inadequate for various enterprisey problems. Both sets of people got the same response: "Rails is intended for a particular problem space. You are free to use it in any way you like, but its design targets a simple, quality-intensive, small-business use case, and will remain optimized for that use case." (paraphrased.) Rails targeted low-hanging fruit with superior technology, and by doing so changed the world of Web development.

Propellerhead Reason



Propellerhead Reason is a "prosumer" virtual studio application for producing music. Depending who you ask, Reason is either a toy - according to many amateur Cubase and Logic users - or a professional tool - according to professionals like Eminem, Prodigy, London Elektricity, DJ Fresh, Hank Shocklee, and Luke Vibert. If a toy, Reason competes with Fruity Loops, now called FL Studio to diminish the toy-like name; if a pro app, it competes with Cubase, Logic, Reaktor, and Ableton Live.

I read a rumor somewhere that Reason has four times the user base of Logic or Fruity Loops. I haven't been able to substantiate it, but it is definitely a very successful product. Like Rails and Google, Reason disdained popular features thought to be "necessary" in its space when it first launched, and still does so to this day. Where most virtual studio software supported a variety of compatibility architectures designed to accomodate inter-device and inter-software collaboration - MIDI, VST, and at least one other format now lost to the mists of time - Reason initially skipped the entire concept of compatibility. Likewise they skipped, and still skip to this day, the entire concept of recording audio. Instead, they chose a simple design metaphor, and they stuck to it. Recording audio and VST plugins are both out because they don't fit the virtual studio metaphor Reason uses, or its corresponding concept of control voltage, or its unusual corresponding model for MIDI. Reason made simplicity a guiding principle.

Similarly, while most virtual studios "dumbed down" their pro suites for prosumer users - with aggressive condescension, in the case of Digidesign Pro Tools - Reason instead built something which made the consumers immensely happy and then built upwards to the pros. Instead of struggling against Logic, they dropped an atom bomb on Fruity Loops. Reason targeted the low-hanging fruit with superior technology, and produced a marvellous product that still powers a successful business to this day.

The Theme

You may have noticed a theme.

1. Make simplicity a guiding principle
2. Target low-hanging fruit with superior technology

I personally believe that these are essential elements in any and all successful technology projects. I can't prove it; however I can state with confidence that Paul Graham's Viaweb startup matches the pattern as well. This isn't a blog about math, so I'll let someone else figure out the formal proofs. Whether this pattern holds true for all successful technology projects or merely many successful technology projects isn't such an interesting question. Either way, it holds true for successful technology projects. Therefore, if you want a successful technology project, follow these rules.

But what about the monkeys? What about the guys who don't know a damn thing about technology, but their dads own country club memberships? Why is it so much in the world of technology comes down to the fundamental dynamics of an 80s movie? What can we do about it?



The simple, teenage answer is that if you create a successful technology project, the Biffs and the Chips will have to get out of your way. But sometimes it doesn't work that way, or it doesn't work that way fast enough. This is where we get to Ayn Rand.

Ayn Rand



I called her the Libertarian L. Ron Hubbard because both wrote "novels" primarily to sell worldviews. There are certainly differences, but there is that one similarity, and it's an interesting similarity.

She said something brilliant in Atlas Shrugged, and fortunately I do not have a copy of the book here, nor do I have the ability to quote the passage from memory. But I do recall the fundamental idea very clearly: if you want to destroy a system based on lies, just comply with the system, but add nothing of your own.

I've used this against a wide range of irritating people, all to great effect. I've also failed to use it against liars, and when I didn't use it, the liars defeated me. I don't remember why it works, but it works, and I think Rand explains it somewhere in the dense logic problems of her philosophy. Basically, all you do is go along with the BS, but don't waste any energy pretending the BS isn't BS. I'm not saying be a dick about it; just that tolerating bad leadership and copying other people's mistakes are separate things. Tolerate the bad leadership without copying their mistakes.

This simple distinction can serve any programmer very, very well, because, unfortunately, most corporations that programmers work for in any capacity contain systems based on lies. The lie is usually, "you're a programmer, I'm an executive, I know what I'm doing." Actually, the first two parts of that are true; the last part is the lie. That lie gets a lot of corporations into a lot of trouble, and often costs a lot of money.



So on the one hand we have a surefire pair of principles for creating successful technology projects, and on the other we have a nice, simple rule for destroying systems based on lies. And in the hypothetical situation this post opened with, we were tasked with creating successful technology projects in the context of bad corporate strategy - which we have shown is a system based on a lie.

If you've studied the proofs in Euclid's Elements, you know what's coming next:

QED

When you see an executive in your company making some foolish decision, seek to dissuade them; but if they feed you the lie, you know what to do. Comply with their ruling, while adding nothing of your own, and the system of lies will collapse under its own weight. In the meantime, make simplicity a guiding principle, and target the low-hanging fruit with superior technology. Your projects will succeed, and the wasteful corporate foolishness will reveal its true nature soon enough. Don't bother fighting a giant that is going to shoot itself in the foot anyway.

For example, say you've got a corporate decision to build some overspecified monstrosity, when a popular open-source alternative does the job better, more cheaply, more maintainably, with infinitely better documentation in the form of blog posts and support forums all over the world, and therefore with much less overhead. Tolerate the overspecified monstrosity - but use the popular open-source alternative anyway. Say you've got a corporate decision to buy a complex enterprisey package, when you've got developers who can code the core functionality themselves in a few afternoons. Tolerate the complex enterprisey package - but don't actually use it. That would be stupid. Find some useful purpose for the nimble, powerful code, and put it to use. Just do it quietly, without pissing off the VP of Being A Monkey.

Large corporate situations always include low-hanging fruit. Let the overspecified monstrosities fall apart as they are destined to. Let the VP of Being A Monkey spend his gazillions on a one-size-fits-all third-party enterprise app that doesn't do anyone any good. You can't stop them from wasting their time or their money, but you can stop them from wasting your time, and you can always get out of integrating your code with any kind of budget-sucking enterprise money pit if that code targets a sufficiently small, insignificant use case. Don't take on Logic; annihilate Fruity Loops, because then you own the territory completely. Then you have a solid base on which to build, and a small, streamlined project with rock-solid foundations can always pwn an enterprise behemoth that nobody knows how to use.

Quod erat demonstrandum.

Saturday, February 23, 2008

WTF Is This Solar-Powered Rotating Silver Pyramid?

Our next presentation comes to you in sideways vision:



I found it in Hollywood and I have no idea what it does. More background:

Object on light pole of rooftop parking lot. Nearby is a security camera. Several other light poles have cameras; only one has another of these things. The solar panel powers it, I'm sure of that much. It rotates for some reason and appears to be based on designs for Egyptian spaceships. This is from the parking lot next to the Arclight in Hollywood.

If you have any idea what this thing is, please, by all means, comment the YouTube page.

Archaeopteryx: A Ruby MIDI Generator

If you've been following my tweets, my tumblelog, my RubyForge projects, and my conference schedule, in minute, up-to-the-minute detail, you already know about this, but for the overwhelming majority of humans on Earth, this qualifies as news, so:

I've been building a Ruby MIDI generator called Archaeopteryx. It builds on code from Practical Ruby Projects to create a system for auto-generating, self-modifying music.

Earlier screencasts, 5 and 11MB in size:

Aleatoric Hip-Hop
Dynamic Techno

Screencast developed this morning:



The Vimeo conversion destroyed some of the low end of the audio, so it sounds a bit better in real life, but hey, Vimeo's got HD, it looks great in full-screen mode, they support artists much better and more enthusiastically than YouTube, and it's free.

Anyway. Couple interesting lessons from a programming standpoint.

First, the Pragmatic thing that you should learn a new language every year - maybe. But you should also learn new paradigms and new problem spaces. I'm getting a lot out of this, and I think learning the differences between Python and Ruby is at most equivalent in brain-stretchy to learning the differences between Web programming and algorithmic composition. Second, although I think the Lispers over-rate their language, I think there must be some truth to Paul Graham's remarks about Lisp being well-suited to exploring unfamiliar problem domains, because I found exploring in a lambda-oriented/list-oriented way much quicker and cleaner than exploring in an object-oriented way. I've posted before about learning some other stuff too.

You can grab the code if you wanna:

svn checkout http://archaeopteryx.rubyforge.org/svn/

Expect more to come from this thing, but so far, so good.

Update: For some reason my commentary on my own code is wrong. probabilities is the probability matrix; the things I point to and call probability matrices (for some idiotic reason) are actually just lists. In fact really it's just a probability hash, but what's going on there actually is an implicit matrix, because the indices are used to map the lambdas to specific beats, which is why I used each_with_index instead of the more generally preferable inject.

Thursday, February 21, 2008

Waiting For Hillary To Tweet Me Back

Power Surrenders Nothing Without Struggle

Never has.

Never will.

Password v1.1

After several days of using password, I finally asked it for a password it didn't have, and consequently added error-handling. Password's now on v1.1.

sudo gem update password

w00t.

Wednesday, February 20, 2008

ActiveRecord & Ruby2Ruby: This Is Where The Magic Happens

People say that Rails is full of magic. Do you ever wonder where the magic happens?



Peeking behind the curtain and seeing what makes the so-called "magic" tick is easy.



I'm in a Rails app which has ActiveRecord User models, each of which has an association class specified:

belongs_to :choice

I install the gem, and then I call

Ruby2Ruby.translate(User)

And Ruby2Ruby returns the class, translated from an object in memory into Ruby code.

In terms of the methods I get back, there are several association-related methods, and one class method I defined when creating the class itself. Conspicuously absent are methods like find and save - that's because they live on ActiveRecord::Base, not User itself.

Unfortunately, when you call

puts Ruby2Ruby.translate(ActiveRecord::Base)

...things kind of blow up. The same is true for ActionController. For some reason, just as it can show you User but not ActiveRecord::Base, it can show you UsersController but not ActionController. Ruby2Ruby can apparently only reveal some of the magic you might want to see.

But it's still a handy trick. Many Rails plugins of the acts_as_foo family add methods to models, and you should be able to see those changes with Ruby2Ruby. It's a very useful way to shed some light on what actually happens inside Rails' "magic."

Best Blog Evar

Stuff White People Like

Venture Capitalists Are Paris Hiltons

The pitch presentation for VCWear, a game-changing startup which sells $100 t-shirts to silly wankers who spend their whole lives trying to pretend that peeing away the fortunes their great-grandparents created makes them businessmen.



(Actually, I met a couple people who met Paris Hilton, and they had nothing but good things to say about her - but still.)

Monday, February 18, 2008

Sexy Resource: ActiveResource .xml Stripper

Following on the heels of Dapper Resource, Snazzy Resource, and Spiffy Resource, Sexy Resource is yet another ActiveResource plugin by Giles Bowkett.

script/plugin \
install http://sexy-resource.googlecode.com/svn/trunk/active_resource_xml_stripper/


Sexy Resource is useful for when you're using ActiveResource against non-Rails-y, non-XML-y Web services. You pass in a :dot_xml => false, and a regex steals away the .xml usually appended to ARes URLs.

For instance, we needed to authenticate user credentials against a CMS called Alfresco:



The self.foo methods allow you to take your URL outside the boundaries of Rails' convention over configuration assumptions, but there's one more step to take, and the :dot_xml => false takes it.

(It's not actually that sexy, but after the first three plugins, someone said I should name the next one Sexy Resource. The next one turned out to involve a stripper, sort of, so it seemed like the right time.)

Sunday, February 17, 2008

Against Filibusters

Raganwald interrupted his own blog post on a fascinating, excellent book with one of those little poll widgets:



It looks like he did it as a rhetorical device, but honestly, I got distracted by the poll, and now I don't have time to finish reading the post.

Here's an excerpt from a comment I left on the poll site:

I think Yegge is way off in his megapost filibusters considered useful theory...

Filibusters work in blogs if your sole goal is volume, because many people read blogs not to actually learn anything but to while away the hours at work. Those who prefer to actually learn stuff probably prefer shorter posts. That at least is my theory.


Most people who read blogs do it for both reasons - sometimes to learn something, and sometimes to veg out. I think blogging in Yegge's filibuster style probably favors the veg-out use case by a wide margin. Certainly, it requires readers with at least some time on their hands. Everybody needs to veg out now and then, but biasing your blog in favor of readers with a lot of time on their hands sounds like a mistake.

After all, if you've got a lot of time on your hands, there's always the archives.

BIL And TED's Excellent Adventure

They're Wiliam S. Preston, Esquire and "Ted" Theodore Logan - and together, they're Wyld Stallyns.

Saturday, February 16, 2008

Ask A Silly Question

Somebody got the idea that it would be cool to do a survey mapping programming languages to religions.

This person did not arbitrarily constrain the list of religions.



After Artemisian, my favorite religions on this list are probably Discordianism, Impossible To Explain, Mix Of Occult Ideas, Haitian Voodoo, Jedi Knight, Functional Programming, New Agey Stuff, and I'm Writing My Own.

You kind of have to wonder how the person who set this thing up didn't anticipate these results. I mean it can't have been that much of a surprise.

Four Flavors Of Ruby Awesome (Most Via Err)

Hazelnut Twitter Agent Observatory Awesome

Citrus Single-File Rails Widgetry Awesome

Dark, Bittersweet SVN RSS Awesome

Juicy Iller Than Ill With Skill Awesome

I'm So Glad I Don't Live Anywhere Near Silicon Valley Any More

Bradley Horowitz: On Leaving Yahoo

Friday, February 15, 2008

sudo gem install password

password: brain-dead simple password storage
by Giles Bowkett
http://gilesbowkett.blogspot.com/2008/02/sudo-gem-install-password.html

== DESCRIPTION:

password is a simple command-line tool to store your INESSENTIAL passwords.

All passwords stored with password are stored as plain text in a file called
".they_stole_my_facebook_login_oh_noez" in your home directory.

If you store vitally essential personal information using password, you are a
dumb motherfucker. (Or, at least, much braver than smart.)

password exists because I could not give a flying fuck if somebody steals my
Twitter login and because I discovered research which indicates removing
registration requirements from online communities actually IMPROVES the
signal-to-noise ratio, consistently, by a nontrivial margin.

OpenID is not the solution. Not giving a fuck is the solution. Therefore I
present password - the crucial tool for people who don't give a fuck.

== CODE EXAMPLES:

password -g twitter
password --get twitter

Prints your Twitter username and password to the terminal.

password -a

Prints every known username/password combo to the terminal.

password -s twitter wilbur s3cr3t
password --set twitter wilbur s3cr3t

Sets your password entry for "twitter" to username "wilbur" and password
"s3cr3t".

password -G twitter wilbur
password --generating_set twitter wilbur

Sets your password entry for "twitter" to username "wilbur" and a 10-digit
autogenerated password, and prints the new username/password combo.

password -l 23 -G twitter wilbur
password --length 23 --generating_set twitter wilbur

Sets your password entry for "twitter" to username "wilbur" and a 23-digit
autogenerated password, and prints the new username/password combo.

All password really does is store a hash as YAML, so if you store a password
as "twitter" you won't be able to retrieve it as "Twitter." That's the bad
news; the good news is that if you really care about security, you can use
nicknames for sites, instead of their literal names, and combine that with
password's ability to create arbitrary-length autogenerated random passwords.

You could even do this:

password -l 235_000 -G username_for_site_joe_told_me_about_that_one_day_at_ramen_place x
password -l 235_000 -G password_for_site_joe_told_me_about_that_one_day_at_ramen_place x

The output would be:

username_for_site_joe_told_me_about_that_one_day_at_ramen_place
username: x
password: [235,000-character randomly-generated string]
password_for_site_joe_told_me_about_that_one_day_at_ramen_place
username: x
password: [235,000-character randomly-generated string]

Blam. Usernames and passwords that can stand up to rainbow hashes. Secure forever
against everybody but Joe, and whoever you guys went to the ramen place with that
one day. (And maybe your waiter or waitress, depending on the status of their
eavesdropping skills.)

== REQUIREMENTS:

* ActiveSupport
* Must not be an idiot

== INSTALL:

* sudo gem install password

== LICENSE:

(The MIT License)

Copyright (c) 2008 Giles Bowkett

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


All profanity and jokes aside, most passwords are a ridiculous waste of time. There is only one useful purpose served by putting a password on my Twitter account - it helps Twitter protect the value of their investment by dramatically reducing the risk of spam. Removing registration improves signal-to-noise ratios, Bayesian filters can make spam a nonissue, and registration doesn't prevent anyone from making spoof logins, so registration is basically just a waste of time. The only benefit here is that Twitter's engineers don't have to write a Bayesian filter and their suits don't have to grow balls. That benefit is entirely theirs, not mine - but I'm the one who has to do the remembering.

That's abusing your customers. It's abuse that everybody is used to, but it's still abuse, and I for one don't have time for it. It's like when banks shut down all their human tellers and replaced them with ATMs, and then added ATM fees - we pay for the privilege of saving them money. It's ridiculous. If some arbitrary social networking site wants me to protect the value of their investment, subsidize their managerial cowardice, and reward their engineers for not doing any heavy lifting, I think they should be paying me for that effort. It's crowdsourcing at its worst.

Password-protection on my Twitter account, or Reddit, or del.icio.us, or for the love of God instructables.com - what the hell were they thinking? - does absolutely nada for me personally, and wastes my valuable time every day, because there is always some stupid Web site demanding my password when it doesn't even need it for any useful purpose. This is especially true given that there's plenty of evidence that requiring unnecessary passwords hurts your business.

If you work in a large corporation, you're especially screwed. The password gremlins lurk everywhere, like roaches that can type - they change the network password every week, or the Exchange server password every three and a half hours except on Tuesday, etc., etc. Nobody should have to waste their time on that stuff.

Thursday, February 14, 2008

Wednesday, February 13, 2008

Tuesday, February 12, 2008

I'm Proud Not To Understand has_many :through

Here's why:



I went into the gem directory for has_many :through, and used ack - a superior alternative to grep - to find every "class FooError" line in the file associations.rb, which defines has_many :through and all its friends.

Of the nine error classes defined by the entire associations system in Rails, seven of them deal with has_many :through.

My instinct before this discovery was to avoid has_many :through whenever I could. Having made this discovery, I really have to say, avoid has_many :through whenever you can. What used to be casual laziness on my part has morphed into deliberate strategy without changing in any important practical aspect. has_many :through error classes outnumber all other error classes in Rails' associations internals combined by a factor of more than three to one. That's a sure sign that code needs refactoring.

I wish I knew the refactoring to make here, ideally well enough to implement it and patch Rails, or even just enough to suggest a solution, but I don't. I do feel very confident that this code will be refactored at some point, because the Rails community and core team are diligent, skilled, and kinetic, but until that time, I'm going to avoid building my house on sand.

In a situation like this, learning has_many :through, unless absolutely necessary, reeks of an inability to make strategic decisions about what you learn and when. I developed this ignorance through being lazy, but maybe that's a virtue. Maybe Larry Wall was right. Certainly, if you're hiring Rails programmers, and a candidate says "I know the associations internals inside-out, except for has_many :through," that shouldn't be interpreted as almost being an expert in Rails' associations internals. That should be interpreted as not only being an expert in Rails' associations internals, but also having the good judgement to recognize when a subject is not worth obtaining expertise in.

I'm not saying learning has_many :through makes you an idiot. Any time you have knowledge somebody else needs, that's a good thing for both of you. But during the period after the dot-com crash, I tried two tactics to increase the amount of money I could charge for my programming services. One of them failed spectacularly, and one of them succeeded wonderfully. The failure was learning the skills that had the most job posts; the success was learning the skills that most engaged my own curiousity. I learned Java and got nothing out of it; I studied Bayesian filtering for fun and did consulting work in Bayesian filtering through my activity on a Ruby mailing list.

In a sense, my laziness around has_many :through was again prompted by a lack of curiousity; it just looked like too much trouble to bother with. The moral here is that if something seems boring, skip it. Trust your intuition. It's there for a reason.


Update: I don't do comments, but I've known Jack Nutting online since the early days of Schwa, and he says:

g-man, you are totally wrong on this! I've been using has_many :through extensively, and I've never encountered any of those errors, not once. I haven't looked at the code, but I'm guessing that those error conditions are there to warn people if they're using it in the wrong situation (anywhere that isn't basically a many-to-many modeled with an entity table in the middle [the "through" table] that has foreign keys to the other two). If so, it makes sense that it warns of exponentially more kinds of problems, since the fact that it uses 3 tables instead of 2 means that there are exponenentially more ways you can screw it up by using it in the wrong places, compared to normal associations.

That being said, the true abomination is certainly has_and_belongs_to_many, which besides being pretty limited also doesn't seem to warn you of incorrect usage in any meaningful way at all. At least, that's how it seemed during my very first few hours using rails, almost two years ago (shortly thereafter has_many :through came out, and I haven't used habtm since).


The thing is, though, I'm not saying it isn't useful - I'm saying it's got too many error messages. Anything that confuses that many people in that many different ways is almost guaranteed to get cleaned up and clarified at some point in the future, and I'm just saying that I'm going to avoid it for as long as I can, because if I wait long enough, I can skip all the confusion. Sooner or later it'll end up elegant - the way lib/initializers cleaned up the ugliness of config/environment.rb - and I'd really rather just wait until then. I'll learn it if I have to, but the Ruby culture isn't about learning things because you have to, and if you look at learning as an investment, none of my best payoffs have come from things I learned because I had to. I always profit more from things I learn for fun. Everything you learn because you have to takes time away from things you learn because you want to, and for me personally the fun learning always pays off better than the obligated learning, so it's wise for me to minimize the obligated and maximize the fun.

Make ActionView::Helpers Available To Models And Controllers

Ara T. Howard accomplishes this with some nice handy code; I took it one further, and with his permission, packaged it up as a plugin.

Use cases like

render :text => link_to "foo", "bar"

are impossible in Rails controllers by default; but with this plugin, you can do this:

render :text => helper { link_to "foo", "bar" }

Nice and easy.

Install here:

script/plugin install \
http://universally-available-helpers.googlecode.com/svn/trunk/universally_available_helpers

Call Immediately



Here's why this matters: think of political outrage as electrical potential. Every time we get the Democratic Party to stand up to the Bush administration and shut down their criminal antics, we reduce the ambient electrical potential. However, every time the Dems are tolerating criminal behavior without growing a backbone, the ambient political outrage potential increases, both against the Bush administration and against the Dems. This is not additive; it's exponential.

If the ambient political outrage potential builds to a sufficient degree, the first thing to ground that potential will carry a massive charge. That's how riots happen. When the riots in 1992 happened, during the reign of the first King George, I wasn't surprised; the ambient political outrage potential was already very high.

That potential is very high today as well. I feel absolutely certain that if we don't do something to stand up to the Bush scumbags, the ambient potential will intensify sufficiently to cause riots. Innocent people get hurt in riots.

Call. You'll get a voicemail: just say you're calling to demand no immunity for telecoms who spied on Bush. It's clear. It's simple. It takes fifteen seconds.

Do it right now.

Sunday, February 10, 2008

Programming Languages Are A Superset Of DSLs

In the sense that anyone who makes a DSL does so within a subset of a fully-featured programming language, of course, this is obvious.

But if you're just looking at that end of the truth, you don't see the interesting part.

The interesting part is that English can express anything a programming language can express, but English was also designed to accomodate ambiguities and nuances that are useful when speaking to people, but not useful when proscribing actions for Turing machines.

Programming languages are subsets of English specific to the domain of Turing machines.

(They aren't inherently subsets of English - that's an incidental attribute, rather than an inherent one - but all the programming languages I'm aware of are subsets of English, even my current favorite, which comes from Japan.)

This may only be interesting to linguists, but it explains certain mysterious phenomena linking poetry to programming languages.

ActiveResource Instance Authentication Plugin: Dapper Resource

Presenting Dapper Resource, an ActiveResource instance authentication plugin.

script/plugin install
http://dapper-resource.rubyforge.org/svn/active_resource_instance_authentication


You know how you define ActiveResource models like this?



That self.site call hits a site class method which then generates an ActiveResource::Connection object and makes it a class-level attribute.

But there's a problem. A user later needed HTTP authentication on their ARes models, so it was added in the same place:

self.site = "http://user:pass@localhost:12345/"

But if you store the username and password at the class level, you can't map your Rails app's users directly to your Web service's users - because each instance of the class will have different credentials. (I've posted about this before - here and here.)

Dapper Resource moves the connection object down to the instance level. For find calls, I wish I could say I wrapped the generation of a new connection object with appropriate credentials up into the ARes initialize, but I didn't. I was in a hurry, and I always go by YAGNI unless given a really good reason not to. So for find, you can just pass in an arbitrary connection object to find itself. (Also, if you don't provide specific connections, your ARes models will default to the class-level connection.)

Here it is:

script/plugin install
http://dapper-resource.rubyforge.org/svn/active_resource_instance_authentication


Hope you dig it.

Saturday, February 9, 2008

It's Not Meta, It's Just Programming

Here we have an RSpec set of examples for a Rails plugin which modifies ActiveResource.



I've complained about the complexity of this plugin - check the link for context - but really it's a testament to Ruby's flexibility. You can pretty much redesign ActiveResource's entire approach to HTTP connection in 137 lines of code over the course of a couple days.

Brag brag brag. That's not the point. The point is, this bit here.



This is one of the less frequently-used idioms in Ruby, but it's very handy. With it you can add methods to any arbitrary object.



Typically, the example use cases you see for "metaprogramming" are often complex and involved. My use case here was very simple: my spec wouldn't run because I didn't have a particular method on my mock; so I added the method to the mock. Boom. Done. Nothing clever, nothing deep. You need the method? Add the method. It's that simple.

Metaprogramming isn't really such a big deal.

Ultra-Balkanization Makes Lisp Autistic

An interesting perspective. It's too long, so I extracted key sentences expressing the idea I find interesting: Lisp's hyper-specific DSL features make Lisp programs autistic.

A language is an interface between programmers and hardware, so it has social/psychological/pedagogical features which are just as important as its formal properties. Many Lisp zealots dismiss the language's failures as "merely social", but that's missing the purpose of a language entirely. Normal syntax gives you a feeling of what's idiomatic vs. what's weird. With sexps, it's much harder to create, maintain and convey such opinions in the code's appearance. Without this consensus you'll have a hard time building a functional social group. Since with Lisp you essentially design your own single-use language for your application, you're the only one in the world using that language variant.

Wired: Oh How The Mighty Have Fallen

About 13/14 years ago I wrote a couple short pieces for Wired. At the time I was thrilled to bits.



In those days, many of the people on the cover of Wired were cyberpunk novelists. Today, that's so atypical of the magazine that finding images to support the assertion is a project in and of itself. They're out there on the Web, but they're hard to find. Google only keeps alive information that our culture is actively remembering on a day-to-day basis.



Possibly my favorite piece in Wired ever was a short story by Neal Stephenson called Hack The Spew.



When was the last time you saw a short story dominate the cover of a magazine?

Wired was better than people today remember it being.



Today, in the current issue of Wired - which features a TV comedian with no technological background at all on its cover - there's a short opinion piece called Unmasked By Facebook which paraphrases Hack The Spew. The paraphrase is unwitting, and nearly witless as well.

I miss the old Wired. I miss the old sci-fi as well. In general it seems to me that the community which once spent its money and time on great sci-fi novels now spends its money and time building incredible sci-fi widgets. At a recent combined gathering of several geek get-togethers in Los Angeles - Geek Dinner and Dorkbot at Machine Project - I met people who were building all kinds of cool, weird shit. (And I was only there for the first hour!) One of the people I met told me about a guy he knew who had built a bona fide laser gun. It used UV light in some manner, so the actual laser beam was invisible to the human eye, but it could be used to melt holes in concrete walls near-instantaneously from significant distances. He said that if you think about it, a laser is ultimately pretty steampunk technology.

I had no idea what he meant by that observation, but it sounded really cool. I think, if I had understood what he was talking about, I would have really gained something from the observation - something not just technological, but cultural as well. But I really don't know what he meant. A good sci-fi writer could have given me the perspective to understand it, but it seems as if the good sci-fi writers have all retired or gotten boring. So I'm at a loss as to what to do with this information. However, I can tell you for a fact that the fascist elements in this country seizing power illegally and planning for martial law are going to find a handmade invisible laser up their ass if they're ever seizing power illegally from me.



Obviously this kind of confrontational attitude could have some negative pratical repercussions. On the other hand, if you think about it, and if you actually read the links, you might realize, there's fertile ground there for some incredible sci-fi. That's the real reason I miss the old Wired. Not just nostalgia - I think that the overall decline in cyberpunk means a loss for everyone.

It's actually really valuable for a society to be able to ask questions like that - "What if Blackwater really starts imposing martial law - and what if geeks shoot back with handmade UV lasers?" - just to see what the answers might be. In today's political climate, especially just a year or two ago, I think people were afraid to even voice these thoughts in public - which is in itself kind of scary - but it's a really valuable thing to do, because ultimately, science fiction is how a culture thinks ahead. People who don't think ahead don't make good decisions. The same is probably true for societies. If you look at how the Republicans consistently denied global warming, and the crazy weather we're having these days, especially the storms killing people and demolishing cities all over the South, you might start to think, maybe it's a good thing when societies think ahead.

Friday, February 8, 2008

Rails: Aspect-Oriented Programming Use Case

You won't hear a lot of people talk about aspect-oriented programming in Rails, but it's worth learning about. Here's why.

Yesterday I wrote my third ActiveResource plugin since December. I'll probably release it in a few days.

This plugin had to kind of rewire ARes. As anyone who builds ARes apps knows, the first thing you do when you start is you define the resource's base URL.



If you want to do your authentication with HTTP Basic Authentication, you just add a username and password to the URL.

self.site = "http://user:pass@localhost:12345/"

But what if you need to do that authentication for more than one user? Not such an uncommon use case, when you think about it. What if your Web service parcels out resource access on a user-by-user basis? Each logged-in user will have different access priveleges, so that the username/password info varies at an instance level, but it's specified at a class level.

Problem.

You can't just dynamically reassign self.site on the class. If you modify class-level information on an instance-by-instance basis, you basically set yourself up for a race condition the minute two instances of the same class need to modify the same info. This means you've got to modify ActiveResource in a pretty fundamental way.

Of course, this is easy with Ruby. But it isn't necessarily pretty.



Although my plugin is working well, and will probably not need any difficult work to get working perfectly, the design could be better. Basically, my client programmer(s) needed me to preserve the original behavior but enable instance-level auth in many cases. So I have this kind of hybrid thing going on.



You can use the usual class-level site config, or pass a connection object, and Rails knows whether to use the run-of-the-mill class-level config, or the more specific config.

Implementing this involved a lot of duplication.



Additionally, the connection isn't actually on the instance, it's just this loose-floating connection object, unanchored to any particular model or controller or anything.

I want to change that, and probably will, but even when I do, it won't alter the fundamental hackiness of the code. Either way, it's going to involve a certain amount of repetition. The reason is I'm working against a fundamental aspect of ARes' design, and doing so necessarily requires a fair amount of work, because I'm going against the grain.

Faced with a situation like that, of course, I want to fix it, and this is where I kind of get to the point, which is always a good thing to do, sooner or later. There are two ways to solve this particular problem, and each of them has its tradeoffs.

Redesign

The obvious answer is to simply redesign ActiveResource to store this information on an instance basis, or possibly to design a layer of abstraction where you separate your Web service's HTTP auth from the auth on your ARes app. In either case, redesign is a lot of work. It also kind of blurs the line between redesign and refactoring, because if you look at ARes from the outside, it looks like a refactoring - a change in design with no change in behavior - but if you've got a bunch of ARes code, in practical terms, it's a redesign.

Aspect-Oriented Programming

This is exactly the kind of problem AOP was designed for. Authentication is what AOPers call a cross-cutting concern - it's something many different objects in your system will need to do, but putting it on all the objects in the system is a terrible failure of separation of concerns. In this specific plugin, I'm moving the authentication from a model's class to its instances, but you could make a pretty strong argument that neither the class nor the instance actually has anything to do with authenticating, and therefore neither of them should even have that information in the first place.

The AOP answer is to use "stand-alone modules called aspects" to isolate behavior required across several business models in such a way that they are available to all those objects without being contained within them. This prevents tight coupling of logically independent functionality, and drives you towards a good design.

Aspect-oriented programming is very much a product of the Java world, and the Rails community has taken a pretty antagonistic attitude towards that community in the past.



In my opinion, it was certainly a fight worth picking, but it got way out of hand. Certainly, a generic knee-jerk hostility towards Java ideas is still to be found in the Rails world, but throwing that same kind of attitude at aspect-oriented programming could be a "throwing the baby out with the bathwater" kind of mistake. It's entirely possible that aspect-oriented programming inevitably becomes useful for any sufficiently complicated framework used for at least a certain threshold number of different applications.

Scotland On Rails Conference Badges For Your Blog

I created a couple speaker badges for the upcoming Scotland on Rails conference:

Small:



Large:



If you're not speaking at the conference, but you are going, and excited about it, there's no point spurning that enthusiasm, so I made a badge for that too:

Small:



Large:



Of course the cool part is that this is a European(ish) conference, so I get to bring in that cool European design style. Europeans make Helvetica look good.

There are two other European Ruby/Rails conferences happening just before Scotland on Rails - Euruko and Ruby Fools - which, for those of you in Europe, makes a really nice excuse for a holiday your boss might even pay for.

Maybe Running Obama Is Wise

Having ranted about the foolishness of running Obama, I'm just going to give the other point of view some consideration. In fairness, there may be some widsom to running him as well.

The Republican system for "winning" elections doesn't consist solely or even primarily of putting dishonest individuals in key election-specific positions. That's really just a support effort to their broader tactic of getting out the vote. Tom Frank documented how this works; essentially the party chooses policy decisions that please big business, and chooses rhetoric which motivates economically disadvantaged and poorly educated Christians, which is an extremely large voting bloc. Then big business contributes cash, and economically disadvantaged, poorly educated Christians contribute staggering amounts of volunteer time in very large numbers.

Currently, this coalition isn't holding together as well as it has in the past. I'd like to think that the economically disadvantaged, poorly educated Christians have started to wake up and realize that a party which gives you rhetoric but not policy isn't really on your side, they're just saying things you want to hear. However, whether that inevitable moment has arrived yet for the Republicans or not, they haven't been able to engage the evangelical Christians this election, and the current Republican front-runner is a man who has severly criticized evangelical Christians in the Republican party, yet recently reversed his position, and said quite bluntly that he's doing it because they get out the vote:

RUSSERT: But, Senator, when you were on here in 2000, I asked you about Jerry Falwell, and this is what you said:

MCCAIN (clip, 3/5/00): Gov. Bush swung far to the right and sought out the base support of Pat Robertson and Jerry Falwell. Those aren’t the ideas that I think are good for the Republican Party.

RUSSERT: Do you think that Jerry Falwell’s ideas are now good for the Republican Party?

MCCAIN: I believe that the “Christian Right” has a major role to play in the Republican Party. One reason is because they’re so active and their followers are.




Under circumstances like this, it could be incredibly useful if the Democrats were somehow to come up with a candidate who can get out the vote in record numbers.



I still think we need to attack the problem of voter fraud head-on, and that failing to do so is just pathetic, cowardly bullshit, and I still massively preferred Edwards' policies to Obama's, but there's a lot to be said for somebody who can get out the vote.

Thursday, February 7, 2008

Matz' Blog: New Ruby Web App Framework

Dan Yoder was thrilled to discover his new Ruby Web app framework Waves blogged about by none other than Matz himself.

My very erudite friend Josh Criz provided an approximate translation:



To answer Josh's question, I believe it means Matz is saying that the appearance of additonal Web frameworks in Ruby is good for the overall Ruby Web app ecosystem.

Campfire CC.rb Plugin v0.3 Released

The new version of my Campfire CC.rb plugin allows you to specify Campfire options on either a per-project or per-install basis, depending on your needs, and gives you an extremely and deliberately naive Subversion uptime monitor, along with SSL support.

svn checkout http://campfire-ccrb.rubyforge.org/svn campfire-ccrb

Spiffy Resource v0.1.1 Released

Spiffy Resource, my YAML-schema ActiveResource forms initializer plugin, is v0.1.1 today. My it grows so fast. New feature is boolean attribute methods.

Too tired to explain more.

script/plugin \
install http://spiffy-resource.rubyforge.org/svn/active_resource_form_handlers_initializer

Wednesday, February 6, 2008

Misgivings About The Democratic Candidates

Here's what I don't like about the Democrats, who I very grudgingly count myself among:

We're running either a black man or a woman. That means that even if we lose, we get to feel good about ourselves. Either way, our self-respect and our pride are covered. We've got an insurance policy on our egos. What we don't have is a ruthless strategy for winning. We're prioritizing great television and our own feelings over political strategy and success.

The last time we made this choice, we lost.

I would feel so much better about the Democratic candidates if we were going to be feeling a sort of sick guilty sensation about what we had to do to win. Because that's what success in politics feels like. Politics is not a place where you win by feeling good about yourself. You don't get a law degree and a political career by hugging teddy bears. Lawyers are fighters. The whole job of a lawyer is to fight. They fight in the courts, wearing suits, but they are above and beyond all other concerns fundamentally people who fight each other for a living.

When you elect somebody, you're hiring somebody to fight for you. I don't want a good-looking, well-educated, charming, well-spoken black man to fight for me. I want a do-dirt nigga who'll kick a motherfucker in their balls. Because that's what the Republicans bring us every time. They might be bringing us white do-dirt niggas, but a do-dirt nigga is a do-dirt nigga. We win elections and they still take power! Obama is great, but when the Republicans are setting rows of men armed with shotguns between black people and their polling places, like they did in 2000, winning the black vote doesn't mean a whole lot. These motherfuckers are criminals, and they are raping our political process. The US government doesn't even allow the United Nations to send voting inspectors to observe our elections any more.

Obama wrote a book called The Audacity Of Hope, but it might make more sense to talk about The Wankery Of Upper-Class Delusional Self-Indulgence. I got to shake Obama's hand, and it was a thrill. I get the same thrill of optimism as most people from Obama. But I can totally see people smiling and remembering how the Democrats lost in 2008, and saying, "but what a great time we had." And I know that there are plenty of people who believe that America isn't ready for a black president, and many of those people who believe that thing are black people who can't even get seated at a family restaurant.

I mean, let's face it, they would know. All this talk about is America ready for a black president is just ridiculous when there are little black kids wondering when America will be ready to sell them some tater tots and let them sit down.

A year ago I posted that the Democrats never win the presidency unless they run white men from the South. Let's quit sucking our own dicks and run a white man from the South. Let's just do what it takes to win, for once. Is that really so hard?

Since that post last year, the amazing, kick-ass candidate who was a white man from the South has dropped out of the race, mainly because the media consistently ignored him, and we've got a really close nomination race. We're either going for a black President and a female VP, or the other way around. We might lose, but it'll be a precedent-setting election. (Like that's supposed to mean something.)

Meanwhile, the suicide rate among US soldiers is five attempts per day, and if your son kills himself in Iraq, the Army won't even count him among the casualties of war. And nobody even wants to know about the Iraqi casualties.



That's what's going on while the Democrats are mounting a "fun" campaign which is guaranteed to be "historic" and make you feel like some kind of hero even if your team loses. That's horribly irresponsible. As angry as anyone who loses a family member to suicide in Iraq might be at "President" Bush, as angry as any crippled Iraqi 11-yr-old or his anguished father might be at "President" Bush, they should be more angry at the Democratic Party, who took historic wins in 2006 over anti-war outrage and then refused to even consider impeachment.



What's really amazing about all this is that nobody seems worried about the possibility of election fraud, despite the precedent set in 2000 and even though election officials in the election-deciding state of Ohio recently went to jail for election fraud perpetrated during the 2004 election. We're supposed to believe that the same people who seized power illegally two Presidential elections in a row will just somehow roll over and play by the rules this time.

I hope Obama wins. I really do. But I wish we weren't running him. I'm sick and tired of this crap. We're up against people with a proven history of election fraud. Do we chart out a strategy for preventing election fraud? Or do we chart out a strategy for feeling like elections really, really matter, even though we know we can win the election and still not take power?

Is that not the most pathetic type of CYA behavior the world has ever witnessed?

What are we preparing for?

Cui bono?

Sometimes I think Democrats deserve Republicans. But the rest of us deserve something better.








(Sorry about all the negativity, but they put CNN on in my gym every morning. I'm looking for another gym.)

Monday, February 4, 2008

Zed Shaw Podcast

Zed has some points to make and does so with much colorful language. I normally bleep out expletives, but with Zed it didn't feel right (and there are so many it would have taken a long time).

The file (18mb mp3)
The site

David Chelimsky On TDD "vs." BDD

Does BDD kick TDD's butt?



It's kind of nice when you see people in the programming community just stop and take a break from the endless variations on "my dad could beat up your dad" that pass for "discussion" in programming circles.

Sunday, February 3, 2008

Photography: Staircase & Trees

Over the past few days.



Saturday, February 2, 2008

Arc Is A Continuation Server



Arc bills itself as a revolutionary Lisp, but it isn't one. Responding to criticisms like this, Paul Graham posted an argument for Arc's awesomeness recently. Although that argument invokes a lot of discussion of language features, its only concrete example leverages the power of a server which can maintain closures across multiple page loads.

If you've been reading this blog for a while, that power is a familiar concept.

Arc looks like Seaside with parentheses.

And that's for a very good reason - Avi Bryant has said that Paul Graham's comments on using continuations and closures in Web apps inspired some of Seaside's design.

The cool thing about Arc is that people can now ask questions like "which continuation server's the best?"

Update: Turns out people could already ask that question. Arc is just one new possible answer. Matt S Trout and Brennan Falkner clued me in to a Perl continuation server and three Lisp ones (one Scheme, two CL). Come to think of it, Jifty also has continuations, but may or may not be a continuation server. (Jifty docs are pretty weird to figure out.)

Spiffy Resource: ActiveResource View/Form-Handler Initializer

A lot of people think that you can just treat ActiveResource models and ActiveRecord models as entirely identical things, with only one difference - that one is loaded from the database and the other is loaded from the network. That isn't the case, but it's a very common misconception, and the reason it's such a common misconception is because that if ActiveResource did work that way it'd be incredibly useful.

It's not that hard, however, to make it true. A little while back I released Snazzy Resource, which gives you one piece of the puzzle. This plugin, Spiffy Resource, gives you another piece:

script/plugin \
install http://spiffy-resource.rubyforge.org/svn/active_resource_form_handlers_initializer


Spiffy Resource is based on a strategy I described a few months ago: build an ActiveResource schema dumper. Part of the stumbling block with using ActiveResource models as if they were ActiveRecord models is that ActiveRecord models add on attribute methods at definition, based on a schema dump from the database, and ActiveResource models don't.

In the blog post late last summer I described writing a Rails controller action to dump the schema across the network as XML, and having your ActiveResource app receive that schema and add on attribute methods the same way. This plugin doesn't quite do that, because this time, my client programmer is writing code against a Web service that doesn't come from a Rails app. We could very likely have it dump an XSD, and that could be more portable for a larger number of possible uses, but it was much much simpler just to define a YAML file with, essentially, a schema, and have the plugin load that schema and add attribute methods accordingly.

The win, of course, is that it works for web services that come from Rails apps and web services that don't; and indeed that it works whether or not you have any control at all over the internals of the service. The downside is you have to generate the YAML manually. (However, it should be very easy to write something which parses a Rails db schema dump and turns it into YAML.)

Combine Snazzy Resource with Spiffy Resource, and you should have not only one well-dressed resource, but also a nice, easy, plug-and-play experience developing Rails apps with ActiveResource models.

Friday, February 1, 2008

Avoid This Insanely Stupid Book

If a book carries a warning label which states that I’m putting myself at risk of patent litigation by implementing the ideas in the book, I’ve got a problem with that. A big enough problem that I'm not going to reading it.

Pat Eyler on a new book from IBM which states:

If you want to take our methods and create your own software solution to sell as a product, while we applaud your initiative and enthusiasm, you really should first discuss this with suitable representatives from IBM business development. IBM has sole ownership of all the intellectual property described in this book, all of which is protected by U.S. patents, both granted and pending.

From time to time I'll contact authors to see if I can use the code in their books; both "Practical Ruby Projects" and "The Ruby Way" contain code that has ended up in Ruby music-generation experiements I've done. I think failing to include a license for the code in your book is a very common but very rude faux pas on the part of tech publishers today. But actively prohibiting people from using the code or even the ideas in your book is pretty damn strange. Certainly, if your target market is people who want technical ideas which they can't use explained in great detail, you're not planning to sell a whole lot of books.

Tons Of Interesting News Today

Microsoft trying to buy Yahoo

Hypothalamus plays unexpected role in memory

DNA-assisted crystalline structure design

Israel plans electric car network for 2011

Nanotube radio