<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-16002962</id><updated>2008-07-20T20:12:37.727-07:00</updated><title type="text">The Web and all that Jazz</title><link rel="alternate" type="text/html" href="http://webjazz.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default?start-index=26&amp;max-results=25&amp;redirect=false" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/posts/default" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>288</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><link rel="self" href="http://feeds.feedburner.com/TheWebAndAllThatJazz" type="application/atom+xml" /><entry><id>tag:blogger.com,1999:blog-16002962.post-6776625487573584239</id><published>2008-07-20T20:06:00.000-07:00</published><updated>2008-07-20T20:12:37.875-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git" /><title type="text">Git remote branch notes</title><content type="html">I'm surprised that I still have readers.  All apologies, but things have changed significantly in the past month.  I joined another startup, and have been busy with that.  Mobtropolis is still up and running, however, as it pretty much runs itself.  So no worries about that.&lt;br /&gt;&lt;br /&gt;I've not learned too much, other than how to use git and some things about couchDB on the side, but it should be interesting.  I'll post more about it after we launch, which should be soon.&lt;br /&gt;&lt;br /&gt;Just to throw down some notes that I usually am looking for about git:&lt;br /&gt;&lt;br /&gt;To create the remote branch:&lt;br /&gt;&lt;code&gt;git push origin origin:refs/heads/{branch}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To delete a remote branch:&lt;br /&gt;&lt;code&gt;git push {repo} :heads/{branch}&lt;/code&gt;&lt;br /&gt;where {repo} is "origin"&lt;br /&gt;&lt;br /&gt;I'm not sure how to do this, but it seems like to create new remote branch from local branch: &lt;br /&gt;&lt;code&gt;git push origin {local branch name}"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Anyone know for sure?
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=37ohgj"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=37ohgj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=jWkHsJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=jWkHsJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=wzP3DJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=wzP3DJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=D0Oe5j"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=D0Oe5j" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/341155709" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/341155709/git-remote-branch-notes.html" title="Git remote branch notes" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=6776625487573584239" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/6776625487573584239/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6776625487573584239" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6776625487573584239" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/07/git-remote-branch-notes.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-1989448241996971428</id><published>2008-05-21T13:02:00.000-07:00</published><updated>2008-05-21T13:04:15.552-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facebook" /><category scheme="http://www.blogger.com/atom/ns#" term="emergent systems" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><category scheme="http://www.blogger.com/atom/ns#" term="social networks" /><title type="text">Segmentation of social news sites</title><content type="html">&lt;a href="http://gilesbowkett.blogspot.com/2008/05/summon-monsters-open-door-heal-or-die.html"&gt;Giles Bowkett: Summon Monsters? Open The Door? Heal? Or Die?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have to admit, I almost stopped reading after the first couple paragraphs justifying himself being jerk-ish, but he does have a healthy dose of good points towards the middle.  &lt;br /&gt;&lt;br /&gt;The underlying assumption of 'wisdom of the crowds' is that people make independent decisions, and they have the same amount of time to do it.  Neither are true in social news sites.  The former being untrue because you can up vote stories that are already on the front page.  That just makes it into a positive feedback system that blows up and amplifies small signals.  It's ok when the community is small, but as it gets larger, the more likely that noise will make it.  &lt;br /&gt;&lt;br /&gt;The second point I didn't think about until Giles pointed out explicitly--that since votes come for free, that people that spend their time on the sites are the ones that influence it the most.  &lt;br /&gt;&lt;br /&gt;Combine the two effects, you have a recipe for amplification of noise.  The problem is, you need the amplification mechanisms like up voting on the front page in place when the site is small to grow it, and then when it reaches a certain size, the mechanics of social sites need to change (to what, none of us exactly figured it out yet) to protect the users from themselves.&lt;br /&gt;&lt;br /&gt;I'm venturing to guess personalization and fuzzy segmentation to be one solution.  As &lt;a href="http://paulbuchheit.blogspot.com/2008/03/is-fragmentation-bad.html"&gt;Paul Buchheit mentioned earlier about how twitterers hardly get any spam&lt;/a&gt;, it's because if anyone's saying stuff you don't want to hear, you can just unfollow them.  Twitter works in this regard because there is a built-in small world network with a relatively low transmission rate between nodes (as opposed to facebook which has a small world network, but high transmission rates of information between nodes...which results in lots of unwanted invitations to bite zombies and vampires).  Social sites like Digg, reddit, and hacker news, don't really have a network.  It's just one single "place", where what happens on it affects everyone, and small perturbations get amplified.&lt;br /&gt;&lt;br /&gt;However, I don't think such a strategy would work well in the beginning.  The very thing that helps a small community in the beginning hurts a larger community, and the very thing that would protect a larger community from itself would stunt the growth of a new smaller one.&lt;br /&gt;&lt;br /&gt;I think this would be an interesting topic and ripe for research.  It actually reminds me of ant colonies, where younger ant colonies will act like teenagers, taking more risks, focus on growing, and experimenting.  Older ant colonies are more about taking less risks, maintaining the brood, and surviving.  There's some sort of decentralized mechanism that kicks in for ant colonies to do that, or maybe once they reach a certain size.  I think looking into the literature for that might yield some clues into how to design community sites so that they can grow in the beginning, and not implode when they get bigger.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=36nlb2"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=36nlb2" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=emjuNH"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=emjuNH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=IxfaEH"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=IxfaEH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=oQs2Nh"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=oQs2Nh" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/295295519" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/295295519/segmentation-of-social-news-sites.html" title="Segmentation of social news sites" /><link rel="related" href="http://gilesbowkett.blogspot.com/2008/05/summon-monsters-open-door-heal-or-die.html" title="Segmentation of social news sites" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=1989448241996971428" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/1989448241996971428/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/1989448241996971428" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/1989448241996971428" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/05/segmentation-of-social-news-sites.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-2967588886413569958</id><published>2008-05-02T19:36:00.000-07:00</published><updated>2008-05-02T19:49:15.305-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="marketing" /><title type="text">Make it easy for users to let others know how awesome they are</title><content type="html">I recently got an email from Amy of Blogged.com, as many of you probably have about how she rated your blog.  The editorial list seems pretty spot on, as she did her homework.  However, I think it would have been more useful if the listing was filterable by the different criteria that she used to rank the blogs, such as quality of updates, frequency of posts, etc.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gHN52xJ15r0/SBvQrbvweGI/AAAAAAAAAUg/Sb6KUTJJsj8/s1600-h/image001.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_gHN52xJ15r0/SBvQrbvweGI/AAAAAAAAAUg/Sb6KUTJJsj8/s320/image001.jpg" alt="" id="BLOGGER_PHOTO_ID_5195976039703017570" border="0" /&gt;&lt;/a&gt;This blog got an 8.1, as I don't post all that often.  I try to post only when I have something to say.  But in reality, while 8.1 might sound hot, it puts me way back at beyond page 10 of her list, which I'm sure no one really looks at.&lt;br /&gt;&lt;br /&gt;But this got me thinking about how word of mouth might work.  I suppose one way is to tell people how awesome they are, and encourage them to tell other people how awesome you think they are.  In essence, I guess that's what great products do, right?  They let you get stuff done, quickly, easily, and with a bit of fun, so that you feel like you're awesome.  If you're awesome, you'd like to tell other people how awesome you are. &lt;br /&gt;&lt;br /&gt;This this limited scope, I think something similar for &lt;a href="http://www.mobtropolis.com"&gt;mobtropolis&lt;/a&gt; would make a lot of sense.  One way for people to feel awesome using mobtropolis is if they've had a sense of accomplishment by completing something.  Or, they get a validation of that accomplishment simply by friends commenting on it.  I need to make it easier for this to happen, and I suspect the more it does, the more people will feel good about themselves.&lt;br /&gt;&lt;br /&gt;What about your product or app?  For any particular application, and especially if it's a tool, if you can make a user feel awesome, make it easy for them to let others know how awesome they are.  It can be stats on their accomplishment, or a limited feature only they can access.  Either way, it has to be limited and unique to them, and yet publicly accessible to others.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=EuhwQS"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=EuhwQS" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=tRPMfH"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=tRPMfH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=Nuc4kH"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=Nuc4kH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=35soUh"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=35soUh" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/282502626" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/282502626/make-it-easy-for-users-to-let-others.html" title="Make it easy for users to let others know how awesome they are" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=2967588886413569958" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/2967588886413569958/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2967588886413569958" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2967588886413569958" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/05/make-it-easy-for-users-to-let-others.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-7409032723588370196</id><published>2008-04-16T07:07:00.000-07:00</published><updated>2008-04-16T09:06:51.709-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><title type="text">Going to Startup school</title><content type="html">I'll be going to startup school this weekend in San Francisco.  If you're going to be there, drop me a line at wil @ 3cglabs dt com, and we'll say hello.  It'd be interesting to meet the readers of the blog.  &lt;br /&gt;&lt;br /&gt;If you haven't heard of &lt;a href="http://startupschool.org/ "&gt;start up school&lt;/a&gt;, it's hosted by ycombinator.  The only reason I'm going is because I applied and got in, rather than paying a couple thousand smackeroos for it.  Thank you ycombinator.  I've been unable to go to conferences due to the outrageously high cost of conferences.  But it might be ok, because when I think about it, really fresh and new ideas are usually not at big conferences, but at small little ones that no one knows about yet.  Startup school defn is not unknown, but at least it's comparatively small.&lt;br /&gt;&lt;br /&gt;I'm not sure exactly what to expect, but I know that I'll have to spend the day explaining &lt;a href="http://www.mobtropolis.com/"&gt;mobtropolis&lt;/a&gt; over and over again.  Time to beef up and whittle down that 3 min explanation.  This is something you should do anyway, so work on that! &lt;br /&gt;&lt;br /&gt;In the meantime, I'm looking forward to &lt;a href="http://startupschool.org/schedule.html"&gt;hearing the speakers talk&lt;/a&gt;, and hope I get a lot out of it.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=vmh5Ib"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=vmh5Ib" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=deyIjBG"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=deyIjBG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=6m3HK8G"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=6m3HK8G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=jlVoI3g"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=jlVoI3g" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/271527304" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/271527304/going-to-startup-school.html" title="Going to Startup school" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=7409032723588370196" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/7409032723588370196/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/7409032723588370196" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/7409032723588370196" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/04/going-to-startup-school.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-790297825995033353</id><published>2008-03-31T16:26:00.000-07:00</published><updated>2008-04-08T14:41:05.968-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="mobtropolis" /><category scheme="http://www.blogger.com/atom/ns#" term="facebook" /><title type="text">Gotchas of internal iFrame facebook apps and external web apps using Facebooker gem</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gHN52xJ15r0/R_F3MSbzC0I/AAAAAAAAASY/Prk9VB_zS9U/s1600-h/facebook_app_screenshot.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_gHN52xJ15r0/R_F3MSbzC0I/AAAAAAAAASY/Prk9VB_zS9U/s320/facebook_app_screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5184055699070716738" border="0" /&gt;&lt;/a&gt;A while back, I &lt;a href="http://mobtropolis.blogspot.com/2008/03/mobtropolis-now-accessible-through.html"&gt;added mobtropolis to facebook as an internal app&lt;/a&gt;.  I decided to go with using FBML because there was more support in the how-tos about how to use it, and it looked like tighter look and feel and integration.&lt;br /&gt;&lt;br /&gt;However, unlike many facebook apps, Mobtropolis also exists as a stand-alone external web app.  This decidedly made things a little bit hairier, and I had to &lt;a href="http://webjazz.blogspot.com/2008/02/mime-responder-filter-for-rails.html"&gt;write a custom mime-response filter&lt;/a&gt; to be able to tell whether a call was coming from a web client (HTML), or as an internal facebook app (FBML), in order to authenticate correctly.  I also ended up having to write some &lt;a href="http://webjazz.blogspot.com/2008/02/testing-mime-response-types.html"&gt;custom testing methods for it as well&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Then I &lt;a href="http://webjazz.blogspot.com/2008/03/way-to-think-about-design-for-nave.html"&gt;revamped the layout of mobtropolis&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's major suckage to have to maintain two separate views, so I decided to go with an iFrame with the internal facebook app.  It took a bit of work to convert it to use &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_gHN52xJ15r0/R_PheCbzC1I/AAAAAAAAASg/By0e13gVNBw/s1600-h/facebook_app.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_gHN52xJ15r0/R_PheCbzC1I/AAAAAAAAASg/By0e13gVNBw/s320/facebook_app.png" alt="" id="BLOGGER_PHOTO_ID_5184735502199360338" border="0" /&gt;&lt;/a&gt;iFrames, because authentication gets a little bit more complicated.  However, it's something that I only have to deal with once.  Subsequent changes to the layout won't affect it as much.&lt;br /&gt;&lt;br /&gt;In retrospect, I should have went with using an iFrame from the beginning, though, at the time, mobtropolis was fairly ugly. This is what people call "&lt;a href="http://paulbuchheit.blogspot.com/2008/03/ideas-vs-judgment-and-execution_9197.html"&gt;judgement&lt;/a&gt;", and I made the mistake and it cost me about three weeks. The thing is, you just make the best decision you can at the time, and make sure you can change directions easily.&lt;br /&gt;&lt;br /&gt;There were a couple gotchas when using iFrames.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Double facebook frames on redirect to install page.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;External app's layout is wider than iFrame&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Facebook only sends fb params on the first call to your app&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Hopefully, I'll save you some time, to whomever's looking for this info.&lt;br /&gt;&lt;h4&gt;1) Double facebook frames&lt;/h4&gt;When you use ensure_application_is_installed_by_facebook_user or ensure_authenticated_to_facebook, it will automatically reroute the user to an install page if he didn't install your application.  Problem is, it assumes that you're not in an iFrame.  It ends up that you can override application_is_not_installed_by_facebook_user in your controllers.&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;def application_is_not_installed_by_facebook_user&lt;br /&gt;  redirect_to add_internal_facebook_app_url&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where add_internal_facebook_app_url is an action in a controller (say, my_controller), that renders javascript to change the location of the top frame.  &lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;def add_internal_facebook_app&lt;br /&gt;  render :layout =&gt; false, :inline =&gt; %Q{&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;    top.location.href = "&amp;lt;%= session[:facebook_session].install_url -%&amp;gt;"&lt;br /&gt;    &amp;lt;/script&amp;gt;}&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You have to make sure you connect it as a route in order to redirect it like I did in the overridden application_is_not_installed_by_facebook_user(), in routes.rb under config/&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;map.add_internal_facebook_app('add_facebook_internal_app',&lt;br /&gt;                              :controller =&gt; "my_controller",&lt;br /&gt;                              :action =&gt; "add_internal_facebook_app")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;2) External app is wider than iFrame&lt;/h4&gt;I think there is a way to &lt;a href="http://wiki.developers.facebook.com/index.php/Fb:iframe"&gt;resize the Facebook iFrame&lt;/a&gt;, but I didn't find out about it after I did this.  By default, the Facebook iFrame "smartsizes" itself, to fill out rest of the page.  &lt;br /&gt;&lt;br /&gt;First, I created a stylesheet called fb_internal_layout.css, that had extra stylings that squeezed the interface in a 446px wide iFrame.  Then I included it in the headers of my layouts as:&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;link href="fb_internal_layout.css" id="fb_internal_layout" media="screen" rel="alternate stylesheet" title="Facebook Internal Layout" type="text/css" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;Make sure you &lt;a href="http://www.howtocreate.co.uk/tutorials/javascript/domcss"&gt;include titles in the link&lt;/a&gt;, so that you can actually switch it out.&lt;br /&gt;&lt;br /&gt;Then we use javascript to turn on or off this alternate stylesheet depending on whether we're in an iframe or not.  You can use something like what's described in &lt;a href="http://www.alistapart.com/stories/alternate/"&gt;A List Apart's article on alternate stylesheets to switch out stylesheets&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To detect if I was in an iFrame, I simply checked whether (frames.top == frames.self).  If it was, I turned on the alternate stylesheet.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;3) Facebook only sends fb params on the first call to your app&lt;/h4&gt;This is actually not a problem if you use FBML.  This is also not a problem if you're using iFrames, and you require a user to install your facebook app if they want to see what's on it.  &lt;br /&gt;&lt;br /&gt;However, even though this is how a lot of facebook apps operate, I don't think this is very user friendly.  The user has no way to judge whether they want to install your app or not if they can't even sample it.  I would rather have a user add an app because they want to, rather than getting people that add it, but then remove it shortly after.  This not only gives you an inaccurate indication of how many people really want to use your app, but also annoys the hell out of them.&lt;br /&gt;&lt;br /&gt;But making some pages of an iFrame app to be public is a bit tricky.  Only the first click into your facebook app is there fb_params in the request.  Every subsequent click by a user is in your iFrame, so looks as if the user is actually on the external webpage.  &lt;br /&gt;&lt;br /&gt;There are a couple solutions, but I ended up storing session state that the user made a request from an internal app before.  You can't override params on subsequent requests, so using old fb_params to authenticate is difficult at best.  Using the flag that a user made a request before, this session is likely to be coming from an internal facebook app.  When it comes upon a private page, it should be redirected to install mobtropolis, using 1) detailed above.  This is not a perfect solution, but it covers all cases correctly.  &lt;br /&gt;&lt;br /&gt;This, however, doesn't account for the instance where a user that already installed.  In that particular case, I just went ahead an got a facebook session on every first request to the facebook app.&lt;br /&gt;&lt;br /&gt;Hope that helped, and I hope never to have to mess with this sort of stuff again, and that you don't either.  More interesting posts in the future.  Tip!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=esqUtF"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=esqUtF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=oVAPMjG"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=oVAPMjG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=s1CLtuG"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=s1CLtuG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=IAqO9Mg"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=IAqO9Mg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/262894061" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/262894061/gotchas-of-internal-iframe-facebook.html" title="Gotchas of internal iFrame facebook apps and external web apps using Facebooker gem" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=790297825995033353" title="4 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/790297825995033353/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/790297825995033353" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/790297825995033353" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/gotchas-of-internal-iframe-facebook.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-1106712502018444413</id><published>2008-03-28T10:07:00.000-07:00</published><updated>2008-03-28T12:22:56.898-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mobtropolis" /><category scheme="http://www.blogger.com/atom/ns#" term="design" /><title type="text">A way to think about design for the naïve hacker</title><content type="html">Any technology goes through its phases.  First, there's the discovery of what it is, and along with it, the implementation.  Just actually getting it to work is exciting. and at this stage, obviously usability is really a second thought.  It's really hard enough getting it running in the first place, because of all the details you have to juggle as an innovative maker.&lt;br /&gt;&lt;br /&gt;As a result, we get cool things that are hard to use.  The first washing machines in the early 1800's didn't actually have a plug, because there were no wall sockets.  Where'd you plug it in then?  Your light socket hanging from the ceiling.  That's right.  You'd have to unscrew your lightbulb, and then screw in your washing machine--all the while on a step ladder.  If it went haywire, you'd have a heck of a time unplugging it, and that probably wasn't considered very user friendly.&lt;br /&gt;&lt;br /&gt;Then there's the phase where we've got a handle on how to build it, and the question becomes, how do we make it easy to use and work well?  This is the part where design comes in.  In large part, we've become specialized in what we do.  The innovative builders make things that weren't yet possible possible, and then designers come along and create and experience around it.  Stereotypically, hackers scoff at design.  "It's just icing on the cake!" one might say.  To that, I say, to scoff at design as a hacker is to scoff at implementation as a theorist--both lack appreciation of what's required.&lt;br /&gt;&lt;br /&gt;I don't think it hurts for a hacker to know more about design, and how to think about it.  While you may never be as good at putting on the gloss as a professional, you'll be better able to bridge the gap, which will help you be a better hacker.  Besides, it will help you when you design APIs or public interfaces to your classes.&lt;br /&gt;&lt;br /&gt;On the other hand, you might not need much convincing as a hacker if you are a fan of Apple's products.  The Macbook Air, the iPod, the iPhone are widely touted as the stunning examples of design in technology.  However, as a hacker, it seems like a strange and touchy-feely territory that relies on "taste" and "intuition".  It doesn't have to be that way, as I think there's a good way to approach design, if you can think about it in the right way.&lt;br /&gt;&lt;br /&gt;When people think "design", they usually think of superfluous, yet oddly satisfying lines that swoop or swoosh.  They think of chrome, reflection, or shiny surfaces.  Especially gradients.  whoo.  Lots of smart people in the actual design world have written entire books on "What is design?".  I've never read any of them.  However, I don't think they would do a good job of explaining it in a way that's easier for hackers to think about.&lt;br /&gt;&lt;br /&gt;While there is inherent joy in design for its own sake, I'm going to only tackle a way to think about design for products.  Web products, specifically.&lt;br /&gt;&lt;br /&gt;I think of &lt;b&gt;design as a deliberate attention to detail about the exposed public interface, to do two things:  1) to communicate to your user what your product is, and who your user is to others&lt;/b&gt;. &lt;b&gt;2)&lt;/b&gt;&lt;b&gt; to control a user's experience&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If you have no idea what your product is yet, or is still figuring it out, then there's no point in doing too much design.  Design rests very much on what your product is, how it will benefit your user.  If you haven't figured that out yet, ignore all the comments about how ugly your web app is, and figure out how to make it something that works, or something that people want to use because it's useful, because remember, design isn't about gradients.&lt;br /&gt;&lt;br /&gt;The first part of what I think of as design is communication, usually with little to no words.  It answers questions like, "What is it?"  "How will it benefit me?"  While the questions are deceptively simple, if new users can't tell immediately what it is, and how they'll benefit, they'll move on quickly.  This is something I'm still working on, since people, no matter who they are, have limited time and attention to pay to any new thing.  Pretend like you're talking to your really smart uncle, that is drunk all the time:  Get to the simple point, and make it obvious.&lt;br /&gt;&lt;br /&gt;Beyond the first impression, design of the product has to communicate to the user all the time, to answer questions such as, "How do I do [something I want to do]?" or "Can I do [something I wish I could do?"  This is why designers talk about affordances of buttons, interfaces, and &lt;a href="http://mterry.name/log/2007/10/06/the-nipple-as-bad-design/"&gt;how the nipple is the only intuitive interface&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Last major point on communication, design should allow the product to communicate to the user what the heck it's doing at any one moment that the user would care about at that moment.  If you're at a restaurant, you'd like your waitress to tell you that the food will be arriving in 10 mins, but you don't care what kind of pot the chef is using.&lt;br /&gt;&lt;br /&gt;This sort of emphasis is captured in &lt;a href="http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0385267746"&gt;Don Norman's book on Design of Everyday Things&lt;/a&gt;, where he goes into detail ad nauseum.  I recommend you take a look at it.&lt;br /&gt;&lt;br /&gt;The second part, which is the result of communication, is controlling the user experience.  Of course, the phrase, "user experience" is throw around a lot, and people don't much say what it is either.  One aspect is how a user feels during and after using your product.  Do they feel happy?  Confident?  Like they're having fun?  Or do they feel frustrated?  Powerless?  Incompetent?  Or wasting time?&lt;br /&gt;&lt;br /&gt;Seems like you can't control whether someone's having a bad day or not, but there are certain tricks that designers employ to conjure up feelings.  This works because our brains do a lot in interpreting colors and shapes in our culture.  If you see a felt red with a holly green, you'll automatically think of Christmas, and perhaps your feelings that go with Christmas..  Change the tint slightly, and you can be reminded of traffic lights.  The designer doesn't actually have to do very much, other than to suggest a mood, and the brain will do the rest.  It's a good hack.&lt;br /&gt;&lt;br /&gt;Lastly, part of the user experience is also what using the product says about them to their peers.  This differs from peer group to peer groups, but they all have the same goal:  everyone wants to have their product that brings them higher status in their peer group.  This can be achieved by catering to core values of the peer group.  If the peer group of your users are business people, they'll likely to value efficiency, reliability, and effectiveness.  If the peer group of your users are hackers, they'll likely to value ability, interestingness, and functionality.  If the design of your product can communicate that a user is more [insert core values] in their peer group, they'll probably appreciate the product without knowing why.&lt;br /&gt;&lt;br /&gt;One word of caution is that it's hard to identify the core values of a group if you're not a part of it.  And you can't start with an associated design and work your way back to the core values of a peer group.  This is why a lot of people, when designing for girls, automatically start throwing pink everywhere, and then when the design fails, they wonder where their design went wrong.  If your design doesn't communicate first what it does for a user, and second who a user is, then it's going to fail, no matter how much pink you put on there.&lt;br /&gt;&lt;br /&gt;I recently revamped the layout and the look and feel of &lt;a href="http://www.mobtropolis.com/"&gt;mobtropolis&lt;/a&gt;, which is why there's this post, and the two week hiatus from posting.  You can see a "before" and an "after".&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;br /&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gHN52xJ15r0/R-1BUybzCzI/AAAAAAAAASQ/7kTRcWwzXuY/s1600-h/mobtropolis_screenshot.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: left; cursor: pointer;" src="http://bp1.blogger.com/_gHN52xJ15r0/R-1BUybzCzI/AAAAAAAAASQ/7kTRcWwzXuY/s320/mobtropolis_screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5182870571564862258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt; &lt;div style="text-align:center"&gt;Before (v0.2)&lt;/div&gt;&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gHN52xJ15r0/R-1AlybzCyI/AAAAAAAAASI/fPie9pQYm-M/s1600-h/layout_0_6_active_scenes.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_gHN52xJ15r0/R-1AlybzCyI/AAAAAAAAASI/fPie9pQYm-M/s320/layout_0_6_active_scenes.png" alt="" id="BLOGGER_PHOTO_ID_5182869764111010594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt; &lt;div style="text-align:center"&gt;After (v0.6)&lt;/div&gt;&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;While I can't claim to be a designer by any means, I feel that I was fairly successful in changing the direction of the app as well as invoking a better user experience.  Communication will be an iterative process, as there will need to be some back and forth with users, before things get completely resolved.  Just going through it gave me some thoughts on the matter, and next time, I'll talk about the specific lessons I've learned, and maybe some things to help a hacker or two do basic design.  Til then!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=PDS6rG"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=PDS6rG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=utVopxF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=utVopxF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=miSXjkF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=miSXjkF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=QN70lCf"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=QN70lCf" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/259810992" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/259810992/way-to-think-about-design-for-nave.html" title="A way to think about design for the naïve hacker" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=1106712502018444413" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/1106712502018444413/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/1106712502018444413" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/1106712502018444413" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/way-to-think-about-design-for-nave.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-2785172398128310656</id><published>2008-03-24T09:38:00.000-07:00</published><updated>2008-03-23T04:45:03.582-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><title type="text">The twenty-seven word score club</title><content type="html">Like lots of people on facebook, I've been playing scrabulous on facebook.  I'm not much of a wordsmith, but I have fun playing people.  Justin told me that his goal in life was to span two triple-word scores, to get a 9x word score.  So not to be outdone, I wondered what words would be able to give you a 27-word score if you spanned across all three triple-word scores.  We would need fifteen lettered words.  &lt;br /&gt;&lt;br /&gt;Since you can only put down at most seven tiles per turn, there needs to be a word in-between the triple letter scores to help you fill it out.  These "bridge words" can't already be on the triple word score already, and they must be between two and six letters long on each side, where the total length of both words has to be greater than eight.  &lt;br /&gt;&lt;br /&gt;So I wrote a program in a couple hours to find them.  I did take into account whether a word was possible to make based on the scrabble tile distribution, as well as taking into account blanks.  There's 286 of them thus far in the TWL scrabble dictionary.  I didn't find ones that used more than one bridge word on a side.  The points aren't completely accurate either.&lt;br /&gt;&lt;br /&gt;The first number is the points you'd get, and then the two bridge words.  Based simply on the probability of drawing the numbers from a full bag, "irrationalities" is the most likely word.  (in reality, this never happens, since you need to draw tile in order to place those words to reach the side.)&lt;br /&gt;&lt;br /&gt;459 : irrationalistic : ["ratio", "alist"]&lt;br /&gt;&lt;br /&gt;You can score a whopping 459 points with it.  The word that has the biggest word score is "coenzymatically"&lt;br /&gt;&lt;br /&gt;972 : coenzymatically : ["enzym", "tical"]&lt;br /&gt;&lt;br /&gt;Yes.  "tical" is a word.  &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;ti·cal –noun, plural&lt;br /&gt;1. a former silver coin and monetary unit of Siam, equal to 100 satang: replaced in 1928 by the baht.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;There are quite a number of common words, you wouldn't think, as well as quite a number odd ones.  As a note, the point scores aren't exactly accurate.  I didn't take into account the double letter scores that might occur if you place a letter one it.  But given that the multiplier is 27 here, and I picked the longest bridge words (which usually cover the double letter score), it shouldn't affect it too much.  I had held off posting it until I fixed that, but this was sort of a one off amusement and curiosity, rather than anything significant, so I figured I'd just post it.  Enjoy!&lt;br /&gt;&lt;br /&gt;567 : accountableness : ["count", "lenes"]&lt;br /&gt;648 : accountantships : ["count", "ship"]&lt;br /&gt;486 : administrations : ["minis", "ration"]&lt;br /&gt;648 : ammonifications : ["mon", "cation"]&lt;br /&gt;594 : amorphousnesses : ["morpho", "ness"]&lt;br /&gt;621 : anthropological : ["thro", "logic"]&lt;br /&gt;783 : anthropomorphic : ["thro", "morph"]&lt;br /&gt;594 : antihistaminics : ["his", "aminic"]&lt;br /&gt;540 : antitheoretical : ["tithe", "etic"]&lt;br /&gt;594 : aromatherapists : ["math", "rapist"]&lt;br /&gt;540 : astronautically : ["trona", "tical"]&lt;br /&gt;756 : astrophysically : ["strop", "call"]&lt;br /&gt;675 : astrophysicists : ["strop", "cist"]&lt;br /&gt;540 : atheroscleroses : ["heros", "erose"]&lt;br /&gt;540 : atherosclerosis : ["heros", "eros"]&lt;br /&gt;594 : atherosclerotic : ["heros", "roti"]&lt;br /&gt;540 : authentications : ["then", "cation"]&lt;br /&gt;594 : autoradiographs : ["tora", "graph"]&lt;br /&gt;675 : autoradiography : ["tora", "graph"]&lt;br /&gt;810 : bathymetrically : ["thyme", "call"]&lt;br /&gt;594 : beautifications : ["eau", "cation"]&lt;br /&gt;594 : benightednesses : ["night", "ness"]&lt;br /&gt;675 : blameworthiness : ["lame", "thine"]&lt;br /&gt;540 : brotherlinesses : ["other", "ness"]&lt;br /&gt;486 : businesspersons : ["sines", "person"]&lt;br /&gt;405 : ceaselessnesses : ["easel", "ness"]&lt;br /&gt;729 : chancellorships : ["hance", "ship"]&lt;br /&gt;729 : chemotherapists : ["moth", "rapist"]&lt;br /&gt;810 : cholangiography : ["lang", "graph"]&lt;br /&gt;675 : cholecystitises : ["hole", "titis"]&lt;br /&gt;675 : cholestyramines : ["holes", "amine"]&lt;br /&gt;540 : cholinesterases : ["line", "erase"]&lt;br /&gt;675 : cinematographer : ["nema", "graph"]&lt;br /&gt;729 : cinematographic : ["nema", "graph"]&lt;br /&gt;486 : clandestineness : ["land", "nenes"]&lt;br /&gt;594 : classifications : ["lassi", "cation"]&lt;br /&gt;972 : coenzymatically : ["enzym", "tical"]&lt;br /&gt;648 : comfortableness : ["fort", "lenes"]&lt;br /&gt;567 : commensurations : ["men", "ration"]&lt;br /&gt;594 : commercialistic : ["merc", "alist"]&lt;br /&gt;702 : communistically : ["muni", "tical"]&lt;br /&gt;756 : computerphobias : ["put", "phobia"]&lt;br /&gt;648 : conceivableness : ["once", "lenes"]&lt;br /&gt;567 : concelebrations : ["once", "ration"]&lt;br /&gt;540 : conceptualistic : ["once", "alist"]&lt;br /&gt;540 : conglomerations : ["glom", "ration"]&lt;br /&gt;486 : conglutinations : ["glut", "nation"]&lt;br /&gt;540 : congresspersons : ["res", "person"]&lt;br /&gt;486 : considerateness : ["onside", "ate"]&lt;br /&gt;540 : containerboards : ["tain", "board"]&lt;br /&gt;594 : convertibleness : ["vert", "lenes"]&lt;br /&gt;702 : crashworthiness : ["rash", "thine"]&lt;br /&gt;594 : crotchetinesses : ["rotche", "ness"]&lt;br /&gt;513 : customarinesses : ["stoma", "ness"]&lt;br /&gt;459 : dangerousnesses : ["anger", "ness"]&lt;br /&gt;837 : decarboxylating : ["carbo", "lati"]&lt;br /&gt;810 : decarboxylation : ["carbo", "lati"]&lt;br /&gt;540 : deconcentration : ["once", "ratio"]&lt;br /&gt;540 : deconsecrations : ["cons", "ration"]&lt;br /&gt;621 : dedifferentiate : ["diff", "entia"]&lt;br /&gt;513 : defenestrations : ["fen", "ration"]&lt;br /&gt;513 : delegitimations : ["elegit", "mat"]&lt;br /&gt;567 : delightednesses : ["light", "ness"]&lt;br /&gt;864 : demisemiquavers : ["mise", "quaver"]&lt;br /&gt;810 : denazifications : ["nazi", "cation"]&lt;br /&gt;567 : dialectological : ["alec", "logic"]&lt;br /&gt;486 : diastereoisomer : ["aster", "some"]&lt;br /&gt;648 : dichloroethanes : ["ich", "ethane"]&lt;br /&gt;540 : discontinuances : ["con", "nuance"]&lt;br /&gt;540 : discriminations : ["scrim", "nation"]&lt;br /&gt;486 : disinclinations : ["sin", "nation"]&lt;br /&gt;459 : disintegrations : ["sin", "ration"]&lt;br /&gt;648 : dissatisfactory : ["sati", "factor"]&lt;br /&gt;567 : divertissements : ["vert", "semen"]&lt;br /&gt;675 : dyslogistically : ["slog", "tical"]&lt;br /&gt;567 : eclaircissement : ["lair", "semen"]&lt;br /&gt;486 : educationalists : ["ducat", "alist"]&lt;br /&gt;459 : elaboratenesses : ["labor", "ness"]&lt;br /&gt;459 : emotionlessness : ["motion", "ess"]&lt;br /&gt;756 : encephalographs : ["epha", "graph"]&lt;br /&gt;837 : encephalography : ["epha", "graph"]&lt;br /&gt;675 : enfranchisement : ["franc", "semen"]&lt;br /&gt;621 : epidemiological : ["idem", "logic"]&lt;br /&gt;594 : epistemological : ["piste", "logic"]&lt;br /&gt;540 : epistemologists : ["piste", "gist"]&lt;br /&gt;378 : essentialnesses : ["senti", "ness"]&lt;br /&gt;540 : esterifications : ["rif", "cation"]&lt;br /&gt;594 : eutrophications : ["trop", "cation"]&lt;br /&gt;702 : excrementitious : ["creme", "titi"]&lt;br /&gt;621 : exsanguinations : ["sang", "nation"]&lt;br /&gt;702 : extemporisation : ["tempo", "sati"]&lt;br /&gt;540 : fantastications : ["antas", "cation"]&lt;br /&gt;567 : flibbertigibbet : ["libber", "gib"]&lt;br /&gt;513 : foreordinations : ["ore", "nation"]&lt;br /&gt;567 : fragmentariness : ["ragmen", "rin"]&lt;br /&gt;675 : frightfulnesses : ["right", "ness"]&lt;br /&gt;567 : fundamentalists : ["dame", "alist"]&lt;br /&gt;567 : gentrifications : ["rif", "cation"]&lt;br /&gt;513 : gluconeogeneses : ["cone", "genes"]&lt;br /&gt;513 : gluconeogenesis : ["cone", "genes"]&lt;br /&gt;675 : grotesquenesses : ["rotes", "ness"]&lt;br /&gt;648 : historiographer : ["tori", "graph"]&lt;br /&gt;702 : historiographic : ["tori", "graph"]&lt;br /&gt;432 : houselessnesses : ["ousel", "ness"]&lt;br /&gt;702 : humidifications : ["midi", "cation"]&lt;br /&gt;783 : hypervigilances : ["perv", "lance"]&lt;br /&gt;756 : hypnotherapists : ["not", "rapist"]&lt;br /&gt;567 : identifications : ["dent", "cation"]&lt;br /&gt;459 : illiberalnesses : ["liber", "ness"]&lt;br /&gt;513 : illimitableness : ["limit", "lenes"]&lt;br /&gt;486 : illogicalnesses : ["logic", "ness"]&lt;br /&gt;513 : immaterialities : ["mater", "alit"]&lt;br /&gt;540 : immediatenesses : ["media", "ness"]&lt;br /&gt;459 : inalterableness : ["alter", "lenes"]&lt;br /&gt;459 : inanimatenesses : ["anima", "ness"]&lt;br /&gt;702 : inconsequential : ["cons", "entia"]&lt;br /&gt;567 : inconsiderately : ["cons", "ratel"]&lt;br /&gt;486 : inconsideration : ["cons", "ratio"]&lt;br /&gt;486 : incoordinations : ["coo", "nation"]&lt;br /&gt;567 : incrementalisms : ["creme", "tali"]&lt;br /&gt;513 : incrementalists : ["creme", "alist"]&lt;br /&gt;459 : incuriousnesses : ["curio", "ness"]&lt;br /&gt;567 : indefinableness : ["defi", "lenes"]&lt;br /&gt;486 : indoctrinations : ["doc", "nation"]&lt;br /&gt;540 : indomitableness : ["omit", "lenes"]&lt;br /&gt;648 : inflammableness : ["flam", "lenes"]&lt;br /&gt;513 : instrumentalism : ["strum", "tali"]&lt;br /&gt;459 : instrumentalist : ["strum", "tali"]&lt;br /&gt;540 : instrumentality : ["strum", "tali"]&lt;br /&gt;459 : intolerableness : ["tole", "lenes"]&lt;br /&gt;486 : inviolatenesses : ["viola", "ness"]&lt;br /&gt;459 : irrationalistic : ["ratio", "alist"]&lt;br /&gt;405 : irrationalities : ["ratio", "alit"]&lt;br /&gt;567 : irreconcilables : ["recon", "able"]&lt;br /&gt;729 : kinesthetically : ["nest", "tical"]&lt;br /&gt;648 : lickerishnesses : ["icker", "ness"]&lt;br /&gt;540 : loathsomenesses : ["oaths", "ness"]&lt;br /&gt;621 : magistratically : ["agist", "tical"]&lt;br /&gt;594 : martensitically : ["tens", "tical"]&lt;br /&gt;540 : masterfulnesses : ["aster", "ness"]&lt;br /&gt;621 : mercaptopurines : ["cap", "purine"]&lt;br /&gt;621 : metallographers : ["tall", "raphe"]&lt;br /&gt;702 : methamphetamine : ["eth", "etamin"]&lt;br /&gt;891 : methoxyfluranes : ["ethoxy", "ran"]&lt;br /&gt;729 : methylmercuries : ["ethyl", "curie"]&lt;br /&gt;891 : methylxanthines : ["ethyl", "thine"]&lt;br /&gt;648 : microanalytical : ["roan", "lytic"]&lt;br /&gt;621 : misapplications : ["sap", "cation"]&lt;br /&gt;513 : momentarinesses : ["omenta", "ness"]&lt;br /&gt;486 : monounsaturated : ["nouns", "urate"]&lt;br /&gt;459 : monounsaturates : ["nouns", "urate"]&lt;br /&gt;513 : monumentalities : ["numen", "alit"]&lt;br /&gt;567 : multiplications : ["tip", "cation"]&lt;br /&gt;540 : neurobiological : ["euro", "logic"]&lt;br /&gt;513 : neuroblastomata : ["euro", "stoma"]&lt;br /&gt;783 : neuropsychology : ["euro", "cholo"]&lt;br /&gt;513 : nonbarbiturates : ["barb", "urate"]&lt;br /&gt;486 : nonbelligerents : ["bell", "gerent"]&lt;br /&gt;513 : noncelebrations : ["once", "ration"]&lt;br /&gt;513 : noncooperations : ["coop", "ration"]&lt;br /&gt;594 : nonenforcements : ["one", "cement"]&lt;br /&gt;567 : nonimplications : ["nim", "cation"]&lt;br /&gt;756 : nonphotographic : ["phot", "graph"]&lt;br /&gt;486 : opinionatedness : ["pinion", "ted"]&lt;br /&gt;729 : overextractions : ["ere", "action"]&lt;br /&gt;621 : overmedications : ["med", "cation"]&lt;br /&gt;486 : oversaturations : ["ers", "ration"]&lt;br /&gt;567 : overstimulating : ["verst", "lati"]&lt;br /&gt;540 : overstimulation : ["verst", "lati"]&lt;br /&gt;864 : oxytetracycline : ["tet", "cyclin"]&lt;br /&gt;459 : painterlinesses : ["inter", "ness"]&lt;br /&gt;621 : paragenetically : ["rage", "tical"]&lt;br /&gt;675 : parenthetically : ["rent", "tical"]&lt;br /&gt;648 : parthenocarpies : ["then", "carpi"]&lt;br /&gt;567 : parthenogeneses : ["then", "genes"]&lt;br /&gt;567 : parthenogenesis : ["then", "genes"]&lt;br /&gt;621 : parthenogenetic : ["then", "genet"]&lt;br /&gt;513 : pectinesterases : ["tine", "erase"]&lt;br /&gt;567 : permissibleness : ["miss", "lenes"]&lt;br /&gt;702 : pharmaceuticals : ["harm", "tical"]&lt;br /&gt;729 : pharmacological : ["harm", "logic"]&lt;br /&gt;648 : phenomenalistic : ["nome", "alist"]&lt;br /&gt;675 : photoengravings : ["hot", "raving"]&lt;br /&gt;675 : photoperiodisms : ["tope", "iodism"]&lt;br /&gt;783 : phototelegraphy : ["tote", "graph"]&lt;br /&gt;729 : pithecanthropus : ["theca", "thro"]&lt;br /&gt;648 : planimetrically : ["anime", "call"]&lt;br /&gt;621 : platinocyanides : ["latino", "nide"]&lt;br /&gt;513 : pleasurableness : ["leas", "lenes"]&lt;br /&gt;486 : predestinarians : ["redes", "aria"]&lt;br /&gt;486 : predestinations : ["redes", "nation"]&lt;br /&gt;621 : preestablishing : ["reest", "shin"]&lt;br /&gt;648 : prefabrications : ["ref", "cation"]&lt;br /&gt;594 : preformationist : ["reform", "ion"]&lt;br /&gt;540 : preponderations : ["repo", "ration"]&lt;br /&gt;621 : prepublications : ["rep", "cation"]&lt;br /&gt;513 : presentableness : ["resent", "lenes"]&lt;br /&gt;513 : preterminations : ["rete", "nation"]&lt;br /&gt;594 : prettifications : ["ret", "cation"]&lt;br /&gt;702 : problematically : ["roble", "tical"]&lt;br /&gt;486 : proletarianised : ["role", "anise"]&lt;br /&gt;459 : proletarianises : ["role", "anise"]&lt;br /&gt;675 : proteolytically : ["rote", "tical"]&lt;br /&gt;783 : quantifications : ["anti", "cation"]&lt;br /&gt;729 : rechoreographed : ["chore", "graph"]&lt;br /&gt;621 : recodifications : ["cod", "cation"]&lt;br /&gt;513 : reconcentration : ["once", "ratio"]&lt;br /&gt;513 : reconsecrations : ["cons", "ration"]&lt;br /&gt;486 : reconsideration : ["cons", "ratio"]&lt;br /&gt;459 : redintegrations : ["dint", "ration"]&lt;br /&gt;567 : reductivenesses : ["educt", "ness"]&lt;br /&gt;567 : refrangibleness : ["rang", "lenes"]&lt;br /&gt;513 : regretfulnesses : ["egret", "ness"]&lt;br /&gt;513 : reinvigorations : ["vig", "ration"]&lt;br /&gt;432 : reregistrations : ["egis", "ration"]&lt;br /&gt;567 : respectableness : ["spec", "lenes"]&lt;br /&gt;513 : responsibleness : ["pons", "lenes"]&lt;br /&gt;459 : retroperitoneal : ["trope", "tone"]&lt;br /&gt;540 : retroreflectors : ["ore", "lector"]&lt;br /&gt;594 : rigidifications : ["gid", "cation"]&lt;br /&gt;513 : sacramentalists : ["cram", "alist"]&lt;br /&gt;594 : saponifications : ["apo", "cation"]&lt;br /&gt;810 : saprophytically : ["prop", "tical"]&lt;br /&gt;513 : scintillometers : ["inti", "meter"]&lt;br /&gt;567 : seductivenesses : ["educt", "ness"]&lt;br /&gt;540 : selectivenesses : ["elect", "ness"]&lt;br /&gt;459 : semiterrestrial : ["miter", "stria"]&lt;br /&gt;513 : semitransparent : ["emit", "spare"]&lt;br /&gt;405 : sensationalists : ["sati", "alist"]&lt;br /&gt;459 : sentimentalists : ["time", "alist"]&lt;br /&gt;594 : serviceableness : ["vice", "lenes"]&lt;br /&gt;648 : simplifications : ["imp", "cation"]&lt;br /&gt;594 : slaughterhouses : ["laugh", "house"]&lt;br /&gt;459 : snippersnappers : ["nipper", "napper"]&lt;br /&gt;567 : solidifications : ["lid", "cation"]&lt;br /&gt;594 : solipsistically : ["lips", "tical"]&lt;br /&gt;594 : sophistications : ["phis", "cation"]&lt;br /&gt;540 : spermatogeneses : ["perm", "genes"]&lt;br /&gt;540 : spermatogenesis : ["perm", "genes"]&lt;br /&gt;648 : spinthariscopes : ["pint", "scope"]&lt;br /&gt;567 : sprightlinesses : ["right", "ness"]&lt;br /&gt;540 : stadtholderates : ["tad", "derate"]&lt;br /&gt;864 : straightjackets : ["rai", "jacket"]&lt;br /&gt;540 : stratifications : ["rat", "cation"]&lt;br /&gt;540 : stratovolcanoes : ["rato", "canoe"]&lt;br /&gt;567 : strikebreakings : ["trike", "akin"]&lt;br /&gt;648 : superphenomenon : ["perp", "nomen"]&lt;br /&gt;810 : sympathetically : ["path", "tical"]&lt;br /&gt;351 : tastelessnesses : ["stele", "ness"]&lt;br /&gt;621 : teletypewriters : ["let", "writer"]&lt;br /&gt;567 : thanklessnesses : ["ankle", "ness"]&lt;br /&gt;675 : therapeutically : ["rape", "tical"]&lt;br /&gt;675 : thunderstricken : ["under", "trick"]&lt;br /&gt;432 : toastmistresses : ["oast", "tress"]&lt;br /&gt;432 : traditionalists : ["adit", "alist"]&lt;br /&gt;459 : transaminations : ["ansa", "nation"]&lt;br /&gt;486 : transmigrations : ["ran", "ration"]&lt;br /&gt;621 : trihalomethanes : ["halo", "ethane"]&lt;br /&gt;540 : troubleshooters : ["rouble", "hooter"]&lt;br /&gt;567 : troubleshooting : ["rouble", "hoot"]&lt;br /&gt;513 : troublesomeness : ["rouble", "omen"]&lt;br /&gt;567 : trustworthiness : ["rust", "thine"]&lt;br /&gt;540 : unadulteratedly : ["adult", "rated"]&lt;br /&gt;459 : unalterableness : ["alter", "lenes"]&lt;br /&gt;621 : unanticipatedly : ["antic", "pated"]&lt;br /&gt;513 : unboundednesses : ["bound", "ness"]&lt;br /&gt;729 : unchoreographed : ["chore", "graph"]&lt;br /&gt;459 : uncleanlinesses : ["clean", "ness"]&lt;br /&gt;621 : unclimbableness : ["climb", "lenes"]&lt;br /&gt;702 : uncomplimentary : ["comp", "menta"]&lt;br /&gt;513 : underestimating : ["dere", "matin"]&lt;br /&gt;486 : unearthlinesses : ["earth", "ness"]&lt;br /&gt;702 : unextraordinary : ["extra", "dinar"]&lt;br /&gt;621 : unfavorableness : ["favor", "lenes"]&lt;br /&gt;486 : unguardednesses : ["guard", "ness"]&lt;br /&gt;540 : unrealistically : ["real", "tical"]&lt;br /&gt;513 : unsightlinesses : ["sight", "ness"]&lt;br /&gt;513 : unworldlinesses : ["world", "ness"]&lt;br /&gt;837 : wappenschawings : ["pens", "hawing"]&lt;br /&gt;540 : warrantableness : ["arrant", "lenes"]&lt;br /&gt;486 : westernisations : ["ester", "sati"]&lt;br /&gt;810 : whatchamacallit : ["hatch", "call"]&lt;br /&gt;621 : whippersnappers : ["hipper", "napper"]&lt;br /&gt;621 : wholesomenesses : ["holes", "ness"]&lt;br /&gt;540 : worrisomenesses : ["orris", "ness"]&lt;br /&gt;864 : xeroradiography : ["orad", "graph"]
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=aEelc0"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=aEelc0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=KlHscoF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=KlHscoF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=qFHPG5F"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=qFHPG5F" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=RjcxwOf"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=RjcxwOf" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/256480472" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/256480472/twenty-seven-word-score-club.html" title="The twenty-seven word score club" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=2785172398128310656" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/2785172398128310656/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2785172398128310656" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2785172398128310656" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/twenty-seven-word-score-club.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-298528802745324263</id><published>2008-03-22T06:05:00.000-07:00</published><updated>2008-03-23T19:58:52.623-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="quip" /><title type="text">What do you take away from it?</title><content type="html">This morning, I woke up and read this &lt;a href="http://www.codinghorror.com/blog/archives/001080.html"&gt;particular piece from coding horror&lt;/a&gt;, the well-known blog about software engineering.  Normally, people talking about each others' essays doesn't hold much interest for me to make a comment on.  The recent ones that come to mind are Zed Shaw's &lt;a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html"&gt;Rails is a Ghetto&lt;/a&gt; and Clifford Heath's &lt;a href="http://scri.pt/ruby/monkeypatching-is-destroying-ruby-t17525-40.html"&gt;Monkeypatching is destroying Ruby&lt;/a&gt;.  Even if they bring up the finer points of a subject, it often feels like TMZ.  So even if I hear about it, I go back to coding (which is why you haven't seen me here).&lt;br /&gt;&lt;br /&gt;What prompted me however, is a re-evaluation of the essay--as Jeff Atwood's post made me go back and read Paul Graham's essay to rethink it.  In the end, I didn't think his &lt;a href="http://www.paulgraham.com/boss.html"&gt;latest essay&lt;/a&gt; was the best he's written before, but I don't think his point was to say, "hey you suck ass because you're an employee".  &lt;br /&gt;&lt;br /&gt;Like people that care about their trade, Paul Graham has a certain philosophy on programmers.  Just as the martial arts have different schools of thought of major guiding principles, Paul to has his own school of thought when it comes to programming.  As far as I can tell, he's mostly concerned with hackers, which aren't just people that write code, but people with an attitude of subverting the norm and a cultivated curiosity about the world, mainly expressed through programming.  I think it's these types of people he's mainly trying to reach.  If you're someone that's not like that, but enjoys programming as the way you make a living and don't think about it when you go home the essay simply doesn't apply to you. &lt;br /&gt;&lt;br /&gt;That said, there are advantages to working at a big company.  Aside for the usual concerns about steady paycheck and health insurance, you get a lot more information thrown your way casually by coworkers if you're paying attention.  When you're at a small company, you have to make an effort to read up on industry news--though given how addictive social tech news is, we might not call it 'effort'.&lt;br /&gt;&lt;br /&gt;In addition, there are some types of things that need large company resources to do, even though it's cheaper to start certain types of tech company.  Bio tech comes to mind, as well as chip design.  &lt;br /&gt;&lt;br /&gt;Many times, companies are started because someone was at a big company and they had a good view of the industry and saw a particular need that was unfulfilled.  If the founders weren't at the big company to begin with, they wouldn't have had the wide view of an industry as easily and they wouldn't have been motivated by their company's lack of interest in the niche to go and start their own.&lt;br /&gt;&lt;br /&gt;I venture to guess that Paul writes these sorts of essays on hackers and startups mainly because 1) it's what he knows (and you write best when you write what you know) and 2) there's not enough material out there on it.  If you take into account your friends, your parents, guidance counselors, etc, most everyone can tell you how to go get a job.  However, not many people can write essays on doing a startup.  I believe this particular essay is directed at reaching out to the hackers as described above, and not the general programming audience.  In my mind, it's not a bad thing, because, again, you write what you know.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update:&lt;/i&gt;&lt;br /&gt;This &lt;a href="http://news.ycombinator.com/item?id=143575"&gt;comment and response&lt;/a&gt; to it is one of the better posts that I've read on there.  It's pretty much on the money.  I have an admiration for those that can cut to the chase with clarity in their writing.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=vnRNwj"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=vnRNwj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=MMaDgzF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=MMaDgzF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=UQMfazF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=UQMfazF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=QGpyMbf"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=QGpyMbf" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/256480473" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/256480473/what-do-you-take-away-from-it.html" title="What do you take away from it?" /><link rel="related" href="http://www.codinghorror.com/blog/archives/001080.html" title="What do you take away from it?" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=298528802745324263" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/298528802745324263/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/298528802745324263" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/298528802745324263" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/what-do-you-take-away-from-it.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-6267800387274434189</id><published>2008-03-07T11:07:00.000-08:00</published><updated>2008-03-07T11:37:12.945-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><title type="text">Nine letter word riddle</title><content type="html">It's not too common that I get forwards nowadays.  With the advent of social news, all the stupid links have migrated there.  But on occasion, I'll get one from the older crowd.  This one was a riddle with a movie of the answer attached. &lt;br /&gt;&lt;blockquote&gt;What common English word is 9 letters long, and each time you remove a letter from it, it still remains an English word... from 9 letters all the way down to a single remaining letter?&lt;/blockquote&gt;It was only one answer, however, which it gave as "startling".  I ended up wondering if there were more than one, so I wanted to see how fast I could write something to give me the answer.  It'd be good practice, since most web programming is design and architectural hard, rather than algorithms hard.  Besides, it's been a while since I wrote a recursive function. &lt;br /&gt;&lt;br /&gt;Embarrasingly, it took 2.5-3 hours.  I thought I'd be able to knock it out in one.  I had some problems first removing a single letter from a word.  Ever since I came to Ruby, I hardly ever deal with indicies, so finding those methods took a bit of time.   Then, the recursion is always a bit of a mind bender when you don't do it often. &lt;br /&gt;&lt;br /&gt;I also spent some time looking up what were considered one letter words, but then found out that there's a &lt;a href="http://www.amazon.com/One-Letter-Words-Dictionary-Craig-Conley/dp/B000I5YUK8/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1204917258&amp;amp;sr=8-1"&gt;whole dictionary of one letter words&lt;/a&gt;.  So I only considered "i" and "a" as valid one letter words.  I also threw out all contractions.  &lt;br /&gt;&lt;br /&gt;See if you can write shorter/faster/better code.  It's certainly a better workout than fizzbuzz.  Seeing how it took me a bit, and I didn't clean up the code, I set the bar pretty low to beat.  There were other things that would optimize it.  I didn't throw out shorter words to check in the dictionary if I already checked them in a longer word--ie. I just ran down the list of dictionary words.  Try it out yourself, in whatever language.  (This sounds like a good beginning problem to write in &lt;a href="http://arclanguage.org/"&gt;Arc&lt;/a&gt;.)  Go ahead.  I'll wait.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Got it?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's the list I came up with along with their chains.  You'll notice that it's actually a tree that branches.&lt;br /&gt;&lt;br /&gt;cleansers&lt;br /&gt;[["cleanses", ["cleanse", ["cleans", ["clean", ["clan", ["can", ["an", ["a"]]]], ["lean", ["lea", ["la", ["a"]]]]], ["clans", ["clan", ["can", ["an", ["a"]]]], ["cans", ["can", ["an", ["a"]]]]], ["leans", ["lean", ["lea", ["la", ["a"]]]], ["leas", ["lea", ["la", ["a"]]]]]]]], ["cleanser", ["cleanse", ["cleans", ["clean", ["clan", ["can", ["an", ["a"]]]], ["lean", ["lea", ["la", ["a"]]]]], ["clans", ["clan", ["can", ["an", ["a"]]]], ["cans", ["can", ["an", ["a"]]]]], ["leans", ["lean", ["lea", ["la", ["a"]]]], ["leas", ["lea", ["la", ["a"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;discusses&lt;br /&gt;[["discuses", ["discuss", ["discus", ["discs", ["disc", ["dis", ["is", ["i"]]]], ["diss", ["dis", ["is", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;drownings&lt;br /&gt;[["drowning", ["downing", ["owning", ["owing", ["wing", ["win", ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;paintings&lt;br /&gt;[["painting", ["paining", ["pining", ["piing", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;piercings&lt;br /&gt;[["piercing", ["piecing", ["pieing", ["piing", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;prickling&lt;br /&gt;[["pickling", ["picking", ["piking", ["piing", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]], ["pricking", ["picking", ["piking", ["piing", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;restarted&lt;br /&gt;[["restated", ["restate", ["estate", ["state", ["sate", ["sat", ["at", ["a"]]], ["ate", ["at", ["a"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;scrapping&lt;br /&gt;[["crapping", ["rapping", ["raping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;sparkling&lt;br /&gt;[["sparking", ["sparing", ["spring", ["sprig", ["prig", ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;splatters&lt;br /&gt;[["platters", ["platter", ["latter", ["later", ["late", ["ate", ["at", ["a"]]]]]]]], ["splatter", ["platter", ["latter", ["later", ["late", ["ate", ["at", ["a"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;splitting&lt;br /&gt;[["slitting", ["sitting", ["siting", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]]], ["spitting", ["spiting", ["siting", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]], ["sitting", ["siting", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;stampeded&lt;br /&gt;[["stampede", ["stamped", ["tamped", ["tamed", ["tame", ["tam", ["am", ["a"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;stampedes&lt;br /&gt;[["stampede", ["stamped", ["tamped", ["tamed", ["tame", ["tam", ["am", ["a"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;startling&lt;br /&gt;[["starling", ["staring", ["string", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]]], ["starting", ["staring", ["string", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]], ["stating", ["sating", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;starvings&lt;br /&gt;[["starving", ["staring", ["string", ["sting", ["sing", ["sin", ["in", ["i"]]]], ["ting", ["tin", ["ti", ["i"]], ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;strapping&lt;br /&gt;[["trapping", ["tapping", ["taping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]], ["rapping", ["raping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;stringers&lt;br /&gt;[["stingers", ["stinger", ["singer", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]]]], ["singers", ["singer", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]]], ["singes", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]], ["sings", ["sing", ["sin", ["in", ["i"]]]], ["sins", ["sin", ["in", ["i"]]], ["sis", ["is", ["i"]]], ["ins", ["in", ["i"]], ["is", ["i"]]]]]]]], ["stringer", ["stinger", ["singer", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;stringier&lt;br /&gt;[["stingier", ["stinger", ["singer", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]]]]], ["stringer", ["stinger", ["singer", ["singe", ["sing", ["sin", ["in", ["i"]]]], ["sine", ["sin", ["in", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;trampling&lt;br /&gt;[["tramping", ["tamping", ["taping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]], ["amping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;trappings&lt;br /&gt;[["trapping", ["tapping", ["taping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]], ["rapping", ["raping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;whittlers&lt;br /&gt;[["whittler", ["whitter", ["whiter", ["white", ["whit", ["wit", ["it", ["i"]]], ["hit", ["hi", ["i"]], ["it", ["i"]]]], ["wite", ["wit", ["it", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;wrappings&lt;br /&gt;[["wrapping", ["rapping", ["raping", ["aping", ["ping", ["pin", ["pi", ["i"]], ["in", ["i"]]], ["pig", ["pi", ["i"]]]]]]]]]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And here's my code:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;#!/usr/bin/ruby&lt;br /&gt;&lt;br /&gt;class Array&lt;br /&gt;  def one_less&lt;br /&gt;    total = [self[1..-1]]&lt;br /&gt;    self.each_with_index do |e, i|&lt;br /&gt;      total &lt;&lt; self.values_at(0..i, (i+2)..-1)&lt;br /&gt;    end&lt;br /&gt;    return total[0..-2]&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def sub_words(word)&lt;br /&gt;  result = word.split("").one_less.map { |word_array| word_array.join }.uniq&lt;br /&gt;  result == [""] ? [] : result&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def find_sub_word_chain(word)&lt;br /&gt;  return nil unless @@dict.include?(word)&lt;br /&gt;  return [word] if word.length == 1 &amp;&amp; @@dict.include?(word)&lt;br /&gt;  valid_sub_words = sub_words(word).reject { |w| !@@dict.include?(w) }&lt;br /&gt;  word_chain = valid_sub_words.map do |sub_word|&lt;br /&gt;    chain = find_sub_word_chain(sub_word)&lt;br /&gt;    if chain.nil?&lt;br /&gt;      nil&lt;br /&gt;    else&lt;br /&gt;      if sub_word.length == 1&lt;br /&gt;        chain&lt;br /&gt;      else&lt;br /&gt;        (chain &lt;&lt; sub_word).reverse&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end.compact&lt;br /&gt;  word_chain.empty? ? nil : word_chain&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;@@dict = {}&lt;br /&gt;ARGV[0] ||= "/etc/dictionaries-common/words"&lt;br /&gt;words = File.readlines(ARGV[0]).map { |w| w.chomp }&lt;br /&gt;words.each do |word|&lt;br /&gt;  if word.length == 1&lt;br /&gt;    next unless ["a", "i"].include?(word)&lt;br /&gt;  end&lt;br /&gt;  @@dict[word] = word&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;words.reject { |e| e.length != 9 }.reject { |word| word =~ /'/ }.map do |word|&lt;br /&gt;  chain = find_sub_word_chain(word)&lt;br /&gt;  next if chain.nil?&lt;br /&gt;  puts word&lt;br /&gt;  puts chain.inspect&lt;br /&gt;  puts&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=C3o4dZ"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=C3o4dZ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=NFKnzbF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=NFKnzbF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=oVKb86F"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=oVKb86F" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=aMXyahf"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=aMXyahf" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/247565000" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/247565000/nine-letter-word-riddle-in-ruby.html" title="Nine letter word riddle" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=6267800387274434189" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/6267800387274434189/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6267800387274434189" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6267800387274434189" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/nine-letter-word-riddle-in-ruby.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-6721000843075210467</id><published>2008-03-04T16:52:00.000-08:00</published><updated>2008-03-04T17:02:10.451-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">Foxy Fixtures and polymorphic tables</title><content type="html">Well, I'm behind on everything, which means a bunch of interesting blog posts are queued up.  But this one seemed short enough to warrant a small post.  &lt;br /&gt;&lt;br /&gt;I've always hated fixtures for the same reason that other people hate them, but nonetheless, I've bit the bullet to use them.  Along comes &lt;a href="http://www.ryandaigle.com/articles/2007/10/26/what-s-new-in-edge-rails-fixtures-just-got-a-whole-lot-easier"&gt;Rails 2.0's foxy fixtures&lt;/a&gt;, and it becomes a little easier.  &lt;br /&gt;&lt;br /&gt;What it doesn't detail, however, is how to use your newly foxy fixtures for polymorphic models.  If I have a vote model that I can use to vote on any type of table, with the old fixtures, I'd have:&lt;br /&gt;&lt;pre name="code" class="yaml"&gt;&lt;br /&gt;my_vote:&lt;br /&gt;  id: 1&lt;br /&gt;  account_id: 1&lt;br /&gt;  votable_id: 3&lt;br /&gt;  votable_type: "Scene"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Normally, you just get rid of the foreign keys since it now checks the belongs_to associations of each model, and you can just use the label names.  Same goes with the primary key id.  It'll be autogenerated based on a hash of the fixture label.&lt;br /&gt;&lt;pre name="code" class="yaml"&gt;&lt;br /&gt;my_vote:&lt;br /&gt;  account: my_account&lt;br /&gt;  votable: eat_hotdog&lt;br /&gt;  votable_type: "Scene"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that you're using the association names, and NOT the foreign key name, so you don't use "_id" anymore (that bit me in the ass for a little bit).  &lt;br /&gt;&lt;br /&gt;However, you'll find that with polymorphic models, you won't be able to do that.  Searching around the good 'ole web lead me to find that Foxy Fixtures originally came from a &lt;a href="http://www.railslodge.com/plugins/756-rathole"&gt;plugin called Rathole&lt;/a&gt;, and at the very end of the &lt;a href="http://svn.geeksomnia.com/rathole/trunk/README"&gt;README&lt;/a&gt;, it states:&lt;br /&gt;&lt;blockquote&gt;Also, sometimes (like when porting older join table fixtures) you'll need to be able to get ahold of Rathole's identifier for a given label. ERB to the rescue:&lt;/blockquote&gt;&lt;br /&gt;Go John Barnette!  That way, you can simply do this in your fixtures as a fall-back:&lt;br /&gt;&lt;pre name="code" class="yaml"&gt;&lt;br /&gt;my_vote:&lt;br /&gt;  account: my_account&lt;br /&gt;  votable_id: &lt;%= Fixtures.identify(:eat_hotdog) %&gt;&lt;br /&gt;  votable_type: "Scene"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tip!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=QicRmC"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=QicRmC" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=ZyAD7eF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=ZyAD7eF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=xp1nQjF"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=xp1nQjF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=jyKcrqf"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=jyKcrqf" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/245818958" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/245818958/foxy-fixtures-and-polymorphic-tables.html" title="Foxy Fixtures and polymorphic tables" /><link rel="related" href="http://svn.geeksomnia.com/rathole/trunk/README" title="Foxy Fixtures and polymorphic tables" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=6721000843075210467" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/6721000843075210467/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6721000843075210467" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6721000843075210467" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/03/foxy-fixtures-and-polymorphic-tables.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-2996996696885229731</id><published>2008-02-26T16:51:00.000-08:00</published><updated>2008-02-26T18:53:23.561-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">Testing MIME response types</title><content type="html">I feel like I might have covered this before, but I was looking for a way to test respond_to.  I had found &lt;a href="http://www.lightning-tree.net/2007/05/testing-respondsto.html"&gt;this post&lt;/a&gt; on how to test it, but after looking at it for a while, I found myself rewriting it.  Mainly, I took out parts that convert the Mime types, and inserted Rail's own Mime type objects.  You can use it like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" type="ruby"&gt;&lt;br /&gt;request_mime(:fbml) do &lt;br /&gt;  get :list&lt;br /&gt;  assert_response_mime(:fbml)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;request_mime("text/xml") do &lt;br /&gt;  get :list&lt;br /&gt;  assert_response_mime("text/xml")&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Just include it in your test_helper.rb file in test/&lt;br /&gt;&lt;pre name="code" type="ruby"&gt;&lt;br /&gt;class Test::Unit::TestCase&lt;br /&gt;  include Threecglabs::MimeTestHelpers&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's "mime_test_helpers.rb".  Just throw it in lib/&lt;br /&gt;&lt;pre name="code" type="ruby"&gt;&lt;br /&gt;module Threecglabs&lt;br /&gt;  module MimeTestHelpers&lt;br /&gt;&lt;br /&gt;    def self.included(mod)&lt;br /&gt;      mod.class_eval do&lt;br /&gt;        include MimeRequest&lt;br /&gt;        include MimeAssertions&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    module MimeRequest&lt;br /&gt;      # changes the mime type of the request within the block&lt;br /&gt;      #&lt;br /&gt;      #   request_mime(:fbml) do &lt;br /&gt;      #     get :list&lt;br /&gt;      #     assert_response_mime(:fbml)&lt;br /&gt;      #   end&lt;br /&gt;      def request_mime(mime_type_name_or_extension)&lt;br /&gt;        if mime_type_name_or_extension.kind_of?(String)&lt;br /&gt;          mime_type = Mime::Type.lookup(mime_type_name_or_extension)&lt;br /&gt;        elsif mime_type_name_or_extension.kind_of?(Symbol)&lt;br /&gt;          mime_type = Mime::Type.lookup_by_extension(mime_type_name_or_extension.to_s)&lt;br /&gt;        else&lt;br /&gt;          raise ArgumentError.new("mime type must be string or symbol")&lt;br /&gt;        end&lt;br /&gt;        old_mime_type = @request.accepts&lt;br /&gt;        @request.accept = mime_type.to_s&lt;br /&gt;        yield&lt;br /&gt;        @request.accept = old_mime_type&lt;br /&gt;      end      &lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    # These are assertions to test respond_to, whether they return a specific mime type&lt;br /&gt;    # as a response to a request&lt;br /&gt;    module MimeAssertions&lt;br /&gt;&lt;br /&gt;      # Helps out with response testing, by letting to assert that the most recently-made &lt;br /&gt;      # request responded with a particular MIME extension, like :html, :fbml, :xml, etc.&lt;br /&gt;      def assert_response_mime(expected_mime_type_ext)&lt;br /&gt;        expected_mime_type = Mime::Type.lookup_by_extension(expected_mime_type_ext.to_s)&lt;br /&gt;&lt;br /&gt;        # Mime::Type.parse doesn't parse accept parameters correctly, therefore&lt;br /&gt;        # we account for having multiple types in the accept&lt;br /&gt;        response_mime_types = @response.headers['type'].split(/,\s*/).map do |accept_type|&lt;br /&gt;          mime_type_name = accept_type.split(/;\s*/).first&lt;br /&gt;          Mime::Type.parse(mime_type_name)&lt;br /&gt;        end&lt;br /&gt;        assert_block("Responded with #{response_mime_types.map(&amp;:to_s).inspect} when expecting #{expected_mime_type}") {&lt;br /&gt;          response_mime_types.any? { |response_mime_type| expected_mime_type == response_mime_type }&lt;br /&gt;        }&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Snippet!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=5StZQe"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=5StZQe" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=XOLFcbE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=XOLFcbE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=xtMlQWE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=xtMlQWE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=rUI6qpe"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=rUI6qpe" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/241854949" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/241854949/testing-mime-response-types.html" title="Testing MIME response types" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=2996996696885229731" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/2996996696885229731/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2996996696885229731" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2996996696885229731" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/testing-mime-response-types.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-8764407851877354534</id><published>2008-02-26T15:44:00.000-08:00</published><updated>2008-02-26T16:50:57.262-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">irb console tricks</title><content type="html">&lt;a href="http://errtheblog.com/posts/24-irb-mix-tape"&gt;irb Mix Tape — err.the_blog&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Not a big entry, but I think worth posting because it pays to learn your tools.  I've got no insights of my own to add.  Someone else's tip!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=e4yHKY"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=e4yHKY" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=7oWVgKE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=7oWVgKE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=6SpIf0E"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=6SpIf0E" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=RnO75ne"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=RnO75ne" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/241802202" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/241802202/irb-console-tricks.html" title="irb console tricks" /><link rel="related" href="http://errtheblog.com/posts/24-irb-mix-tape" title="irb console tricks" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=8764407851877354534" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/8764407851877354534/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/8764407851877354534" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/8764407851877354534" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/irb-console-tricks.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-2350685627382275458</id><published>2008-02-20T08:06:00.000-08:00</published><updated>2008-02-26T18:54:58.247-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">Render_to_string only counts if failed</title><content type="html">&lt;a href="http://www.ruby-forum.com/topic/99733"&gt;render_to_string followed by render issues - Ruby Forum&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was puzzled by this yesterday, and good thing I went to do something else instead of tearing my hair out.  Came back fresh today and found this.  Apparently, render_to_string normally doesn't count as a render--given that it succeeds.  If it throws an exception for some reason, then it'll get count as a double render if you rendered elsewhere.  Small tip!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=liByo4"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=liByo4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=SJxJJZE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=SJxJJZE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=sA7uBoE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=sA7uBoE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=xMwAXie"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=xMwAXie" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/238249757" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/238249757/rendertostring-only-counts-if-failed.html" title="Render_to_string only counts if failed" /><link rel="related" href="http://www.ruby-forum.com/topic/99733" title="Render_to_string only counts if failed" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=2350685627382275458" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/2350685627382275458/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2350685627382275458" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/2350685627382275458" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/rendertostring-only-counts-if-failed.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-5769843176979759088</id><published>2008-02-15T20:36:00.000-08:00</published><updated>2008-02-15T20:36:58.771-08:00</updated><title type="text">Energy over Space</title><content type="html">&lt;a href="http://harpers.org/media/slideshow/annot/2008-03/index.html"&gt;Annotation (Harper's Magazine): Keyword: Evil&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's an annotated blueprint of one of Google's datacenters.  While it's all good and well to point these criticisms out, that doesn't mean nothing's being done about it.  Google itself has announced that it was &lt;a href="http://www.google.com/intl/en/press/pressrel/20071127_green.html"&gt;creating a renewable energy R&amp;amp;D group&lt;/a&gt;.  In addition, it's also in the semiconductor's interest to build cooler chips.  Hot chips won't sell as well now that datacenters are concerned with gigaflop per watt.&lt;br /&gt;&lt;br /&gt;I have a gut feeling that if the next president is in tune with what's going on in tech, he/she'd challenge Americans to rise to the occasion to innovate through the energy problems, just as JFK challenged Americans to fly to the moon half a century ago.  I remember in the 90's as a kid, there was a stint of environmentalism.  Captain Planet.  Save the Walrus tshirts.  And then it kinda faded away until now, a whole decade later.  I'm hoping that it's not a fad, like it was in the 90's.  There are plenty of interesting problems in this space.  And I hope we figure them out before we're able to easily colonize other planets.  If space tech supercedes energy tech, then it would end up to be more economical to just ditch a planet once we dirtied it up for another one.  And pity the natives that happened to be living there.  Humans would be the tyrants looking to subjugate other hospitable planets, and not the victims, like so many science fiction stories would have us believe.  It would look like empirialism all over again.  So I hope we figure out this renewable energy stuff before we figure out how to easily colonize outer space.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=g38YJo"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=g38YJo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=glgwd7E"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=glgwd7E" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=YUHrNeE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=YUHrNeE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=hFOhE8e"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=hFOhE8e" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/235918570" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/235918570/energy-over-space.html" title="Energy over Space" /><link rel="related" href="http://harpers.org/media/slideshow/annot/2008-03/index.html" title="Energy over Space" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=5769843176979759088" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/5769843176979759088/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/5769843176979759088" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/5769843176979759088" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/energy-over-space.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-5567339357528679432</id><published>2008-02-13T11:32:00.000-08:00</published><updated>2008-02-13T12:25:50.196-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="mobtropolis" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="facebook" /><title type="text">MIME responder filter for Rails</title><content type="html">I didn't think I had to do this, but I ended up writing a filter that acts like a switch statement for different MIME types.  Let me explain.  Normally, in Rails, you can respond to different requests for different content with something like this:&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;class PostController &lt; ActionController::Base&lt;br /&gt;  def list&lt;br /&gt;    @posts = Post.find(:all)&lt;br /&gt;    respond_to do |format|&lt;br /&gt;      format.html&lt;br /&gt;      format.fbml&lt;br /&gt;      format.xml { render :xml =&gt; @people.to_xml }&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When you have something like this, the browser (or whatever client) can ask for different MIME types.  Here, we can return html to a browser, xml to maybe a data importer, and fbml to facebook.  &lt;br /&gt;&lt;br /&gt;I spent last week integrating &lt;a href="http://www.mobtropolis.com"&gt;Mobtropolis&lt;/a&gt; with facebook.  Mobtropolis doesn't require a facebook account to use it, so like other websites, it has its own authentication mechanism, something like:&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;class PostController &lt; ActionController::Base&lt;br /&gt;  before_filter :website_authenticate_filter, :except =&gt; [:index, :list]&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When I started using &lt;a href="http://facebooker.rubyforge.org/"&gt;facebooker library&lt;/a&gt;, it already came with an authentication before_filter.  That means we have two authentication filters, one native, and one for facebook.  Mobtropolis users don't have to be in facebook to use it, and facebookers don't have to sign up again in mobtropolis to use it.  &lt;br /&gt;&lt;br /&gt;However, since before_filters are executed in succession, it leads to a case where the facebook authentication would be called if html was requested, and vice versa.  The alternative was to take apart both authentication filters, and create a monolithic filter to handle the two different cases.  Instead, I did this:&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;class PostController &lt; ActionController::Base&lt;br /&gt;   before_respond_to_filter :except =&gt; [ :index, :list ] do |format|&lt;br /&gt;    format.html :website_authentication_filter&lt;br /&gt;    format.fbml :facebook_authentication_filter&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That way, I didn't have to mix together the guts of each authentication filter, and it solved the problem of the wrong authentication filter being run.  You can also use it like:&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;class PostController &lt; ActionController::Base&lt;br /&gt;  before_responds_to_filter :only =&gt; :home do |format|&lt;br /&gt;    format.html do |controller|&lt;br /&gt;      return if controller.logged_in?&lt;br /&gt;      controller.send(:redirect_to, :controller =&gt; :home)&lt;br /&gt;    end&lt;br /&gt;    format.fbml :ensure_application_is_installed_by_facebook_user&lt;br /&gt;  end   &lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By the way, I tried to alter the filter_chain as a request came in.  Filter chains are copied and passed around the filters, so you can't write a filter that alters the filter chain.  So don't waste your time crawling around in the guts of Rails to do this like I did.  It's just as well, as that'd be a nightmare to maintain.&lt;br /&gt;&lt;br /&gt;It does have some weaknesses though.  You can only assign the filters to the same set of :except and :only options in the filters.&lt;br /&gt;&lt;br /&gt;It ended up the code for this sort of magic was fairly easy.  I'm not sure if there's an easier way to do what I wanted, but I'll see if Rails core people would find it useful (or not).  In the meanwhile, for those of you Rubyists that have written plugins before that want to play with it.  As with the usual mumbo jumbo, it's provided as is, I'm not maintaining it, and do whatever you want with it:  &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;module Threecglabs&lt;br /&gt;  module Filters&lt;br /&gt;&lt;br /&gt;    # MimeResponderFilter &lt;br /&gt;    module MimeResponderFilter&lt;br /&gt;&lt;br /&gt;      def self.included(mod)&lt;br /&gt;        mod.extend(ClassMethods)&lt;br /&gt;      end&lt;br /&gt;  &lt;br /&gt;      # Filters can respond to different mime types, so that you can use &lt;br /&gt;      # different filters depending on which mime type is being requested&lt;br /&gt;      #&lt;br /&gt;      #   before_responds_to_filter :except =&gt; [:login, :signup, :forgot, :invite_request, :profile] do |format|&lt;br /&gt;      #     format.html :authentication_filter&lt;br /&gt;      #     format.fbml :ensure_application_is_installed_by_facebook_user&lt;br /&gt;      #   end&lt;br /&gt;      #&lt;br /&gt;      # This way, one can take the appropriate actions in setting up authentication &lt;br /&gt;      # from different mime types, and still separate the implemenation of the different&lt;br /&gt;      # kinds of implementations&lt;br /&gt;      #&lt;br /&gt;      # The formats also take blocks, like regular filters&lt;br /&gt;      #&lt;br /&gt;      #   before_responds_to_filter :only =&gt; :home do |format|&lt;br /&gt;      #     format.html do |controller|&lt;br /&gt;      #       return if controller.logged_in?&lt;br /&gt;      #       controller.send(:redirect_to, :controller =&gt; :home)&lt;br /&gt;      #     end&lt;br /&gt;      #     format.fbml :ensure_application_is_installed_by_facebook_user&lt;br /&gt;      #   end&lt;br /&gt;      #&lt;br /&gt;      # NOTE: an :all format defaults to :html, therefore, a format.html is required&lt;br /&gt;      module ClassMethods        &lt;br /&gt;        def before_respond_to_filter(options = {}, &amp;block)&lt;br /&gt;          before_filter MimeResponderFilter.new(&amp;block), options&lt;br /&gt;        end&lt;br /&gt;        &lt;br /&gt;        private&lt;br /&gt;        # This is a call that implements a MIME responder filter&lt;br /&gt;        class MimeResponderFilter#:nodoc:&lt;br /&gt;          attr_reader :filters&lt;br /&gt;          &lt;br /&gt;          def initialize(&amp;block)&lt;br /&gt;            @filters = {}&lt;br /&gt;            block.call(self)&lt;br /&gt;          end&lt;br /&gt;          &lt;br /&gt;          def filter(controller)&lt;br /&gt;            filter = @filters[controller.request.format.to_sym] || @filters[:html]            &lt;br /&gt;            if filter.kind_of?(Proc)&lt;br /&gt;              filter.call(controller)&lt;br /&gt;            else&lt;br /&gt;              controller.send!(filter)&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;          &lt;br /&gt;          # implements the "format.#{mime_type}" part of the filter&lt;br /&gt;          def method_missing(mime_type, method_name = nil, &amp;block)&lt;br /&gt;            if block_given?&lt;br /&gt;              @filters[mime_type.to_sym] = block&lt;br /&gt;            else&lt;br /&gt;              @filters[mime_type.to_sym] = method_name.to_sym&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Snippet!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=MBSdaP"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=MBSdaP" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=aZDxRjE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=aZDxRjE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=kSkb2fE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=kSkb2fE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=4porE0e"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=4porE0e" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/234552961" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/234552961/mime-responder-filter-for-rails.html" title="MIME responder filter for Rails" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=5567339357528679432" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/5567339357528679432/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/5567339357528679432" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/5567339357528679432" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/mime-responder-filter-for-rails.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-6536662981042308334</id><published>2008-02-08T08:27:00.000-08:00</published><updated>2008-02-08T08:29:15.195-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="emergent systems" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title type="text">Erlang Advocacy and the class of problems it solves</title><content type="html">I spend more time than I should reading hacker.news.  Granted, I sometimes feel like it's the US Weekly or Maxim of the tech world, when stories like "5 ways you know you're failing at your start up" and the general hubbub over Facebook back in June or the recent Microsoft and Yahoo buyout.  However, the quality of the comments there is generally high, and on occasion, I'll start replying to a comment, and before I know it, two hours have passed, and it's better off as a blog post.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The challenge of the Erlang advocate is not to convince me, over and over, that Erlang wins its class; the challenge is to convince me that Erlang's class of problem is so important to my life that I should study Erlang rather than vascular surgery, or television repair, or other obscure technical skills that I don't know that much about.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The follow-up question then would be how many existing problems can be converted to the type that Erlang can solve well?  And how many problems previously impractical are now practical to solve?  So if it ends up to be a bigger class than you thought, you may well be limiting the number problems that you can solve easily and practically out of the ones that will be important in the future.&lt;br /&gt;&lt;br /&gt;I like Erlang (aside from some syntax ugliness), so I'll give it a shot.  I think it's important because it allows a program to easier to scale out rather than scale up.  If it was running an algorithm that are parallelize-able, then you can just technically add more cheap processors to it for a speed up, rather than designing a faster processor.  We'd want speedups in this way because CPUs are becoming multi-cores, and to take advantage of them one will have to write some type of parallel program, since it's proven difficult to fully automate parallelizing serial programs.  In addition, with bandwidth pipes getting bigger and the internet more and more pervasive, it is possible that you can leverage other computers you don't own (but given permission) for computational or storage resources in the future most of whom don't belong to a single entity.  (think more SETI@home than Amazon)&lt;br /&gt;&lt;br /&gt;In addition, parallelized systems (not just erlang) can be more fault tolerant and can fail more gracefully (or hobble along, if you'd like to call it that).  Sensor networks are one example.  Instead of a single radar to detect  the environment, you throw a bunch of sensors out there, and they network themselves and report what they see/hear back to you.  If some of them gets destroyed that's ok, because the system's still functioning with less sensors.  &lt;br /&gt;&lt;br /&gt;A swarm of UVAs doing surveillance in an area is another example.  If you have a single computer commanding all the UVAs, it's actually quite hard, because you don't want them to crash into each other, so that's N^2 comparisons (less if you do oct-trees, probably).  And if a target comes into the area, it becomes a non-trivial allocation problem: how do you decide which UVA to assign to monitoring it, and when do you switch them out when their fuel runs low?  It ends up that doing it in with an actor model, where each UVA decides what to do at any given moment (local interactions) might not be optimal, but it's redundant and fault-tolerant.&lt;br /&gt;&lt;br /&gt;Biological systems work this way as well.  Gene expression is actually a network of genes being turned on and off by proteins expressed by other genes being turned on and off recursively.  If one gene can't activate another, it might not always be detrimental, because there might be other pathways to express that gene.  Since I'm not as familiar with the intricacies of biological systems, I'll refrain from saying anymore.&lt;br /&gt;&lt;br /&gt;I was surprised when I was watching a video of Alan Kay talking about OOP that the OOP C++/Java I learned in college wasn't what he had in mind.  Rather, he meant OOP to be more like biological systems and more process orientated.  Encapsulation was only meant so that objects (analogous to actors in erlang) would have to pass messages to each other (method calls).&lt;br /&gt;&lt;br /&gt;So what concrete examples of problems fall into this class Erlang is good at?  The obvious ones are the embarrassingly parallelized algorithms, like genetic algorithms, neural networks, 3d rendering, and if I'm not mistaken, FFTs.  Indexing web pages is another.  But then again there are other algorithms that are inherently serial like protocol handshaking or newton's method.&lt;br /&gt;&lt;br /&gt;I don't know what the ratio is between embarrassingly parallel and Serial problems are, but my gut is that with the advent of multi-cores and availability of the internet, I think there will be plenty of parallel problems to go around.&lt;br /&gt;&lt;br /&gt;Ruby and Haxe language writers are both implementing the actor model like Erlang, if that's any indication of how important they think it is.  While I don't think Erlang will be the 100 year language, the ideas by which it's a poster child will reverberate in the descendant languages for a long time to come.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=QKxQuR"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=QKxQuR" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=jAWT2PE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=jAWT2PE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=ljzYGVE"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=ljzYGVE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=Mn81uVe"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=Mn81uVe" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/231700890" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/231700890/erlang-advocacy-and-class-of-problems.html" title="Erlang Advocacy and the class of problems it solves" /><link rel="related" href="http://news.ycombinator.com/item?id=112035" title="Erlang Advocacy and the class of problems it solves" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=6536662981042308334" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/6536662981042308334/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6536662981042308334" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/6536662981042308334" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/02/erlang-advocacy-and-class-of-problems.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-8962732200521413010</id><published>2008-01-30T12:09:00.000-08:00</published><updated>2008-01-31T05:20:20.034-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><title type="text">How to find multiple file types using linux's "find"</title><content type="html">I've always found *nix's "find" and "grep" rather hard to use.  Not only are there different flavors of regular expressions to use, but mainly different syntax.  For find, the directory you're searching for comes first.  For grep, it comes last.  To find the negation of something, you'd use "-not" and for grep it's "-v".  pain.&lt;br /&gt;&lt;br /&gt;Anyway, been trying to learn my tools better, and I found out &lt;a href="http://xahlee.org/emacs/find_replace_inter.html"&gt;how to grep and replace expressions across multiple files through emacs&lt;/a&gt;.  Since rails uses all sorts of file extensions, naturally, I wanted to &lt;strike&gt;grep for&lt;/strike&gt; find different files types.  I had thought the -name options took regexs (it doesn't), so I had tried it in regex (no go)...only to find that it's something like this:&lt;br /&gt;&lt;pre class="code" name="unix"&gt;&lt;br /&gt;find . -name "*.rb" -o -name "*.rhtml"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the -o is the equivalent of a boolean "or".  small tip...
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=N9Q0Rt"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=N9Q0Rt" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=mRzsHnD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=mRzsHnD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=i6FiLTD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=i6FiLTD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=VoOnQZd"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=VoOnQZd" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/226092985" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/226092985/how-to-find-multiple-file-types-using.html" title="How to find multiple file types using linux's &quot;find&quot;" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=8962732200521413010" title="3 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/8962732200521413010/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/8962732200521413010" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/8962732200521413010" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/01/how-to-find-multiple-file-types-using.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-709512014058815055</id><published>2008-01-29T13:27:00.000-08:00</published><updated>2008-01-29T14:05:11.455-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="barcode" /><category scheme="http://www.blogger.com/atom/ns#" term="advertisement" /><title type="text">2D barcodes rebirth</title><content type="html">Google just announced 2Dbarcodes for print ads, which prompted &lt;a href="http://www.joelonsoftware.com/items/2008/01/29.html"&gt;Joel to talk about the :CueCat&lt;/a&gt;, which was a large failure in the late 1990's.  Wired Magazine sent you these barcode readers shaped like cats with this one issue.  The idea was that you could scan barcodes in print ads, and given the URL encoded in the barcode, it'll take you there in your browser.  I can hear wails of people going, "now why would I want to do that?"  Of course, that's from a lack of imagination.&lt;br /&gt;&lt;br /&gt;Now, ideas are brilliant or stupid only in the right context.  Joel is correct about his assessment of the :CueCat. However, there are instances where it works and is in widespread use.&lt;br /&gt;&lt;br /&gt;Japanese print ads have 2D barcodes on them.  Even &lt;a href="http://plaza.rakuten.co.jp/lmmntgmry/"&gt;blogs and webpages have 2D barcodes&lt;/a&gt;, so you can access information (URL or otherwise) from your phone.&lt;br /&gt;&lt;br /&gt;There are a &lt;a href="http://blogs.zdnet.com/ITFacts/?p=10159"&gt;couple things different there&lt;/a&gt;.  Most Japanese peoples' access to the internet has been through their cell phones, rather than through their computers.  Landlines are much more expensive than having a cell phone.  In addition, the majority of Japanese are in urban areas where they use public transportation.  That gives them a lot of down time to play with their phones.  The print ads in the train have the 2D bar codes on them, so people can check out the ad while they're riding the train.  Given that unless you have a full keypad (real or virtual), it's still harder typing in a phone, than using a 2D barcode.&lt;br /&gt;&lt;br /&gt;That said, I don't think Americans (Don't know about europe) will find as much use for 2D barcodes for print ads, as we drive everywhere.  The tech world has changed a lot since the :Cuecat was around, so I think most of the right players are in place for 2D barcodes. I don't think having 2Dbarcodes in newspapers makes sense.  It makes much more sense for print ads, you can see on the street in strictly urban areas, like New York City.&lt;br /&gt;&lt;br /&gt;If I'm walking around town, I'd find it very handy to be able to check out how many tickets are left for a show and being able to buy tickets for the show from the URL in a 2D barcode on the print ad for a show across town.  It would also be useful if sewn onto tags of pillows, clothing, other products, etc, so that would provide product information, or at least a URL that has the manual, or specs.  That way, if some piece were broken, it'd be an easy way to order replacement parts. &lt;br /&gt;&lt;br /&gt;I think it's a tiny, tiny step into tying the real world with the virtual, and part of the move to form a Clickable Earth.
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=E3hEz7"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=E3hEz7" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=1opBCeD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=1opBCeD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=JoKZsqD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=JoKZsqD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=wLnvRzd"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=wLnvRzd" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~4/225497408" height="1" width="1"/&gt;</content><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/TheWebAndAllThatJazz/~3/225497408/2d-barcodes-rebirth.html" title="2D barcodes rebirth" /><link rel="related" href="http://www.google.com/adwords/printads/ads/barcode/" title="2D barcodes rebirth" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16002962&amp;postID=709512014058815055" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://webjazz.blogspot.com/feeds/709512014058815055/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/709512014058815055" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16002962/posts/default/709512014058815055" /><author><name>Wilhelm</name><uri>http://www.blogger.com/profile/03696320260631888445</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://webjazz.blogspot.com/2008/01/2d-barcodes-rebirth.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-16002962.post-2054034047916784757</id><published>2008-01-27T08:37:00.000-08:00</published><updated>2008-01-27T08:50:04.369-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title type="text">Making sure extra tasks get run when installing plugins with Piston</title><content type="html">When I graduated college, I was a EE major that could code.  However, in hindsight, I don't think I was as good because I had no idea how to put together moderate sized systems or above.  One of the things that I like about Rails is that they have a system for plugins.  I was too uncouth to consider it before.  Once you extract a plugin out, you essentially have to treat it as a separate library or package.  This forces you to encapsulate, because it's a bit of a pain changing plugins.  I know you can extract code out to DLLs or Gems, but I never did it because it seemed like I didn't need it--plus it was extra steps. &lt;br /&gt;&lt;br /&gt;I eventually would want a programming language that lets me extract out libraries inside the language, and make its public interface RESTful, and auto-extern its path in SVN and whatever the equivalent is in distributed version control like git/darcs.&lt;br /&gt;&lt;br /&gt;Recently, I've started using &lt;a href="http://piston.rubyforge.org/usage.html"&gt;Piston&lt;/a&gt;.  It's a ruby plugin manager that's essentially a wrapper around svn:externals.  It's been pretty easy to use.  In addition, my plugins won't get stale.  However, when you install a plugin with piston, you only import the files.  It doesn't actually execute the install.rb file, like &lt;span style="font-style: italic;"&gt;/script/plugin install&lt;/span&gt; would.  I'll try to see if I can submit a patch to piston later, but for now, simply run "install.rb" in the root of the plugin, and it should do the install for you.  small tip!
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?a=hUn0Wp"&gt;&lt;img src="http://feeds.feedburner.com/~a/TheWebAndAllThatJazz?i=hUn0Wp" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=RH2vIQD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=RH2vIQD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?a=pI3UFvD"&gt;&lt;img src="http://feeds.feedburner.com/~f/TheWebAndAllThatJazz?i=pI3UFvD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/