samhuri.net/wayback/@done/2007.06.29-sjs - geeky ramblings.html

1563 lines
81 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>sjs - geeky ramblings</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://feeds.feedburner.com/sjs" />
<script src="http://web.archive.org/web/20070629103138js_/http://sami.samhuri.net/javascripts/prototype.js" type="text/javascript"></script>
<link href="http://web.archive.org/web/20070629103138cs_/http://sami.samhuri.net/stylesheets/application.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- BEGIN WAYBACK TOOLBAR INSERT -->
<script type="text/javascript" src="http://staticweb.archive.org/js/disclaim-element.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/js/graph-calc.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/jflot/jquery.min.js" ></script>
<script type="text/javascript">
//<![CDATA[
var firstDate = 820454400000;
var lastDate = 1325375999999;
var wbPrefix = "http://web.archive.org/web/";
var wbCurrentUrl = "http://sami.samhuri.net/";
var curYear = -1;
var curMonth = -1;
var yearCount = 16;
var firstYear = 1996;
var imgWidth=400;
var yearImgWidth = 25;
var monthImgWidth = 2;
var trackerVal = "none";
var displayDay = "29";
var displayMonth = "Jun";
var displayYear = "2007";
var prettyMonths = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
function showTrackers(val) {
if(val == trackerVal) {
return;
}
if(val == "inline") {
document.getElementById("displayYearEl").style.color = "#ec008c";
document.getElementById("displayMonthEl").style.color = "#ec008c";
document.getElementById("displayDayEl").style.color = "#ec008c";
} else {
document.getElementById("displayYearEl").innerHTML = displayYear;
document.getElementById("displayYearEl").style.color = "#ff0";
document.getElementById("displayMonthEl").innerHTML = displayMonth;
document.getElementById("displayMonthEl").style.color = "#ff0";
document.getElementById("displayDayEl").innerHTML = displayDay;
document.getElementById("displayDayEl").style.color = "#ff0";
}
document.getElementById("wbMouseTrackYearImg").style.display = val;
document.getElementById("wbMouseTrackMonthImg").style.display = val;
trackerVal = val;
}
function getElementX2(obj) {
var thing = jQuery(obj);
if((thing == undefined)
|| (typeof thing == "undefined")
|| (typeof thing.offset == "undefined")) {
return getElementX(obj);
}
return Math.round(thing.offset().left);
}
function trackMouseMove(event,element) {
var eventX = getEventX(event);
var elementX = getElementX2(element);
var xOff = eventX - elementX;
if(xOff < 0) {
xOff = 0;
} else if(xOff > imgWidth) {
xOff = imgWidth;
}
var monthOff = xOff % yearImgWidth;
var year = Math.floor(xOff / yearImgWidth);
var yearStart = year * yearImgWidth;
var monthOfYear = Math.floor(monthOff / monthImgWidth);
if(monthOfYear > 11) {
monthOfYear = 11;
}
// 1 extra border pixel at the left edge of the year:
var month = (year * 12) + monthOfYear;
var day = 1;
if(monthOff % 2 == 1) {
day = 15;
}
var dateString =
zeroPad(year + firstYear) +
zeroPad(monthOfYear+1,2) +
zeroPad(day,2) + "000000";
var monthString = prettyMonths[monthOfYear];
document.getElementById("displayYearEl").innerHTML = year + 1996;
document.getElementById("displayMonthEl").innerHTML = monthString;
// looks too jarring when it changes..
//document.getElementById("displayDayEl").innerHTML = zeroPad(day,2);
var url = wbPrefix + dateString + '/' + wbCurrentUrl;
document.getElementById('wm-graph-anchor').href = url;
//document.getElementById("wmtbURL").value="evX("+eventX+") elX("+elementX+") xO("+xOff+") y("+year+") m("+month+") monthOff("+monthOff+") DS("+dateString+") Moy("+monthOfYear+") ms("+monthString+")";
if(curYear != year) {
var yrOff = year * yearImgWidth;
document.getElementById("wbMouseTrackYearImg").style.left = yrOff + "px";
curYear = year;
}
if(curMonth != month) {
var mtOff = year + (month * monthImgWidth) + 1;
document.getElementById("wbMouseTrackMonthImg").style.left = mtOff + "px";
curMonth = month;
}
}
//]]>
</script>
<style type="text/css">body{margin-top:0!important;padding-top:0!important;min-width:800px!important;}#wm-ipp a:hover{text-decoration:underline!important;}</style>
<div id="wm-ipp" style="display:none; position:relative;padding:0 5px;min-height:70px;min-width:800px; z-index:9000;">
<div id="wm-ipp-inside" style="position:fixed;padding:0!important;margin:0!important;width:97%;min-width:780px;border:5px solid #000;border-top:none;background-image:url(http://staticweb.archive.org/images/toolbar/wm_tb_bk_trns.png);text-align:center;-moz-box-shadow:1px 1px 3px #333;-webkit-box-shadow:1px 1px 3px #333;box-shadow:1px 1px 3px #333;font-size:11px!important;font-family:'Lucida Grande','Arial',sans-serif!important;">
<table style="border-collapse:collapse;margin:0;padding:0;width:100%;"><tbody><tr>
<td style="padding:10px;vertical-align:top;min-width:110px;">
<a href="http://wayback.archive.org/web/" title="Wayback Machine home page" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wayback-toolbar-logo.png" alt="Wayback Machine" width="110" height="39" border="0"/></a>
</td>
<td style="padding:0!important;text-align:center;vertical-align:top;width:100%;">
<table style="border-collapse:collapse;margin:0 auto;padding:0;width:570px;"><tbody><tr>
<td style="padding:3px 0;" colspan="2">
<form target="_top" method="get" action="http://wayback.archive.org/web/form-submit.jsp" name="wmtb" id="wmtb" style="margin:0!important;padding:0!important;"><input type="text" name="url" id="wmtbURL" value="http://sami.samhuri.net/" style="width:400px;font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;" onfocus="javascript:this.focus();this.select();" /><input type="hidden" name="type" value="replay" /><input type="hidden" name="date" value="20070629103138" /><input type="submit" value="Go" style="font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;margin-left:5px;" /><span id="wm_tb_options" style="display:block;"></span></form>
</td>
<td style="vertical-align:bottom;padding:5px 0 0 0!important;" rowspan="2">
<table style="border-collapse:collapse;width:110px;color:#99a;font-family:'Helvetica','Lucida Grande','Arial',sans-serif;"><tbody>
<!-- NEXT/PREV MONTH NAV AND MONTH INDICATOR -->
<tr style="width:110px;height:16px;font-size:10px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="28 May 2007"><strong>MAY</strong></a>
</td>
<td id="displayMonthEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight:bold;text-transform:uppercase;width:34px;height:15px;padding-top:1px;text-align:center;" title="You are here: 10:31:38 Jun 29, 2007">JUN</td>
<td style="padding-left:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="11 Aug 2007"><strong>AUG</strong></a>
</td>
</tr>
<!-- NEXT/PREV CAPTURE NAV AND DAY OF MONTH INDICATOR -->
<tr>
<td style="padding-right:9px;white-space:nowrap;overflow:visible;text-align:right!important;vertical-align:middle!important;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" title="19:56:04 May 28, 2007" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wm_tb_prv_on.png" alt="Previous capture" width="14" height="16" border="0" /></a>
</td>
<td id="displayDayEl" style="background:#000;color:#ff0;width:34px;height:24px;padding:2px 0 0 0;text-align:center;font-size:24px;font-weight: bold;" title="You are here: 10:31:38 Jun 29, 2007">29</td>
<td style="padding-left:9px;white-space:nowrap;overflow:visible;text-align:left!important;vertical-align:middle!important;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" title="12:57:48 Aug 11, 2007" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wm_tb_nxt_on.png" alt="Next capture" width="14" height="16" border="0"/></a>
</td>
</tr>
<!-- NEXT/PREV YEAR NAV AND YEAR INDICATOR -->
<tr style="width:110px;height:13px;font-size:9px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight: bold;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="20 Jun 2006"><strong>2006</strong></a>
</td>
<td id="displayYearEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight: bold;padding-top:1px;width:34px;height:13px;text-align:center;" title="You are here: 10:31:38 Jun 29, 2007">2007</td>
<td style="padding-left:9px;font-size:11px!important;font-weight: bold;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://sami.samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="4 Jul 2008"><strong>2008</strong></a>
</td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td style="vertical-align:middle;padding:0!important;">
<a href="http://wayback.archive.org/web/20070629103138*/http://sami.samhuri.net/" style="color:#33f;font-size:11px;font-weight:bold;background-color:transparent;border:none;" title="See a list of every capture for this URL"><strong>23 captures</strong></a>
<div style="margin:0!important;padding:0!important;color:#666;font-size:9px;padding-top:2px!important;white-space:nowrap;" title="Timespan for captures of this URL">3 Mar 06 - 31 May 09</div>
</td>
<td style="padding:0!important;">
<a style="position:relative; white-space:nowrap; width:400px;height:27px;" href="" id="wm-graph-anchor">
<div id="wm-ipp-sparkline" style="position:relative; white-space:nowrap; width:400px;height:27px;background-color:#fff;cursor:pointer;border-right:1px solid #ccc;" title="Explore captures for this URL">
<img id="sparklineImgId" style="position:absolute; z-index:9012; top:0px; left:0px;"
onmouseover="showTrackers('inline');"
onmouseout="showTrackers('none');"
onmousemove="trackMouseMove(event,this)"
alt="sparklines"
width="400"
height="27"
border="0"
src="http://wayback.archive.org/jsp/graph.jsp?graphdata=400_27_1996:-1:000000000000_1997:-1:000000000000_1998:-1:000000000000_1999:-1:000000000000_2000:-1:000000000000_2001:-1:000000000000_2002:-1:000000000000_2003:-1:000000000000_2004:-1:000000000000_2005:-1:000000000000_2006:-1:001102000100_2007:5:001121011211_2008:-1:011100100000_2009:-1:010110000000_2010:-1:000000000000_2011:-1:000000000000"></img>
<img id="wbMouseTrackYearImg"
style="display:none; position:absolute; z-index:9010;"
width="25"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-yellow-pixel.png"></img>
<img id="wbMouseTrackMonthImg"
style="display:none; position:absolute; z-index:9011; "
width="2"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-red-pixel.png"></img>
</div>
</a>
</td>
</tr></tbody></table>
</td>
<td style="text-align:right;padding:5px;width:65px;font-size:11px!important;">
<a href="javascript:;" onclick="document.getElementById('wm-ipp').style.display='none';" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_close.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;margin-bottom:23px;background-color:transparent;border:none;" title="Close the toolbar">Close</a>
<a href="http://faq.web.archive.org/" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_help.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;background-color:transparent;border:none;" title="Get some help using the Wayback Machine">Help</a>
</td>
</tr></tbody></table>
</div>
</div>
<script type="text/javascript">
var wmDisclaimBanner = document.getElementById("wm-ipp");
if(wmDisclaimBanner != null) {
disclaimElement(wmDisclaimBanner);
}
</script>
<!-- END WAYBACK TOOLBAR INSERT -->
<div id="container">
<div id="header">
<h1><span><a href="http://sami.samhuri.net/">sjs</a></span></h1>
<h2>geeky ramblings</h2>
</div>
<div id="page">
<div id="content">
<div class="hentry" id="article-112">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/29/recent-ruby-and-rails-regales">Recent Ruby and Rails Regales</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-28T19:23:00+00:00">on Thursday, June 28</abbr>
<br class="clear" />
<div class="entry-content">
<p>Some cool Ruby and [the former on] Rails things are springing up and I haven't written much about the two Rs lately, though I work with them daily.</p>
<h3>Rails on Rules</h3>
<p>My friend <a href="http://jim.roepcke.com/">Jim Roepcke</a> is researching and implementing a plugin/framework designed to work with Rails called <a href="http://willingtofail.com/research/rules/index.html">Rails on Rules</a>. His inspiration is <a href="http://developer.apple.com/documentation/WebObjects/Developing_With_D2W/Architecture/chapter_3_section_13.html">the rule system</a> from <a href="http://developer.apple.com/documentation/WebObjects/WebObjects_Overview/index.html">WebObjects'</a> <a href="http://developer.apple.com/documentation/WebObjects/Developing_With_D2W/Introduction/chapter_1_section_1.html">Direct to Web</a>. He posted a good <a href="http://willingtofail.com/research/rules/example.html">example</a> for me, but this baby isn't just for template/view logic. If some of the Rails conventions were specified in a default set of rules which the developer could further customize then you basically have a nice way of doing things that you would otherwise code by hand. I think it would be a boon for the <a href="http://activescaffold.com/">ActiveScaffold</a> project. We're meeting up to talk about this soon and I'll have more to say after then, but it sounds pretty cool.</p>
<h3>Sake Bomb!</h3>
<p>I've noticed a trend among some <a href="http://www.railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorial">recent posts</a> about Rake: the authors keep talking about booze. Are we nothing but a bunch of booze hounds?! Well one can hope. There's some motivation to learn more about a tool, having more time to drink after work. This week <a href="http://ozmm.org/">Chris Wanstrath</a> dropped a <a href="http://errtheblog.com/post/6069">Sake Bomb</a> on the Ruby community. Like piston, sake is something you can just pick up and use instantly. Interestingly the different pronunciations of <code>rake</code> and <code>sake</code> help me from confusing the two on the command line... so far.</p>
<h3>Secure Associations (for Rails)</h3>
<p><a href="http://tuples.us/">Jordan McKible</a> released the <a href="http://tuples.us/2007/06/28/secure_associations-plugin-gets-some-love/">secure_associations</a> plugin. It lets you protect your models' *_id attributes from mass-assignment via <code>belongs_to_protected</code> and <code>has_many_protected</code>. It's a mild enhancement, but an enhancement nonetheless. This is useful to enough people that it should be in Rails proper.</p>
<h3>Regular expressions and strings with embedded objects</h3>
<p><a href="http://t-a-w.blogspot.com/">taw</a> taught me a <a href="http://t-a-w.blogspot.com/2007/06/regular-expressions-and-strings-with.html">new technique for simplifying regular expressions</a> by transforming the text in a reversible manner. In one example he replaced literal strings in SQL - which are easily parsed via a regex - with what he calls embedded objects. They're just tokens to identify the temporarily removed strings, but the important thing is that they don't interfere with the regexes that operate on the other parts of the SQL, which would have been very difficult to get right with the strings inside it. If I made it sound complicated just read the post, he explains it well.</p>
<p>If you believe anything <a href="http://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html">Steve Yegge</a> says then that last regex trick may come in handy for Q&#38;D parsing in any language, be it Ruby, NBL, or whataver.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/rails">rails</a>&nbsp;<a href="http://sami.samhuri.net/tags/rails%20on%20rules">rails on rules</a>&nbsp;<a href="http://sami.samhuri.net/tags/regular%20expressions">regular expressions</a>&nbsp;<a href="http://sami.samhuri.net/tags/ruby">ruby</a>&nbsp;<a href="http://sami.samhuri.net/tags/sake">sake</a>&nbsp;<a href="http://sami.samhuri.net/tags/secure%20associations">secure associations</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/29/recent-ruby-and-rails-regales">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/29/recent-ruby-and-rails-regales">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-110">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/26/emacs-tagify-region-or-insert-tag">Emacs: tagify-region-or-insert-tag</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-25T22:13:00+00:00">on Monday, June 25</abbr>
<br class="clear" />
<div class="entry-content">
<p>After <a href="http://sami.samhuri.net/2007/6/26/rtfm">axing</a> half of <a href="http://sami.samhuri.net/2007/6/23/emacs-for-textmate-junkies">wrap-region.el</a> I renamed it to <a href="http://sami.samhuri.net/assets/2007/6/26/tagify.el">tagify.el</a> and improved it ever so slightly. It's leaner, and does more!</p>
<p><code>tagify-region-or-insert-tag</code> does the same thing as <code>wrap-region-with-tag</code> except if there is no region it now inserts the opening and closing tags and sets point in between them. I have this bound to <code>C-z t</code>, as I use <code>C-z</code> as my personal command prefix.</p>
<p><code>&lt;</code> is bound to <code>tagify-region-or-insert-self</code> which really doesn't warrant an explanation.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/emacs">emacs</a>&nbsp;<a href="http://sami.samhuri.net/tags/tagify">tagify</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/26/emacs-tagify-region-or-insert-tag">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/26/emacs-tagify-region-or-insert-tag">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-109">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/26/rtfm">RTFM!</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-25T21:19:00+00:00">on Monday, June 25</abbr>
<br class="clear" />
<div class="entry-content">
<p>I should read the Emacs manual sometime, especially since I have it in dead-tree form. Check out <a href="http://www.gnu.org/software/emacs/manual/html_node/autotype/Inserting-Pairs.html">skeleton pairs</a> in the Emacs manual, or better yet <code>C-h f skeleton-pair-insert-maybe</code>. skeleton-pair has already been massaged to do what you most likely want if you set the correct options. Cool. I like Emacs more every day.</p>
<p>This renders <a href="http://sami.samhuri.net/2007/6/23/emacs-for-textmate-junkies">wrap-region</a> useless, which is great! I like a trim .emacs and .emacs.d.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/emacs">emacs</a>&nbsp;<a href="http://sami.samhuri.net/tags/rtfm">rtfm</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/26/rtfm">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/26/rtfm">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-107">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/25/propaganda-makes-me-sick">Propaganda makes me sick</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-25T10:55:00+00:00">on Monday, June 25</abbr>
<br class="clear" />
<div class="entry-content">
<p>Things <a href="http://arstechnica.com/news.ars/post/20070625-spying-on-campus-fbi-warns-mit-harvard.html">like this</a> in modern times are surprising. Can't people spot this phony crap for what it is?</p>
<p><tt>First they put away the dealers, keep our kids safe and off the streets<br/>
Then they put away the prostitutes, keep married men cloistered at home<br/>
Then they shooed away the bums, and they beat and bashed the queers<br/>
Turned away asylum-seekers, fed us suspicions and fears<br/>
We didn't raise our voice, we didn't make a fuss<br/>
It´s funny there was no one left to notice, when they came for us<br/>
<br/>
<strong>Looks like witches are in season, you better fly your flag and be aware<br/>
Of anyone who might fit the description, diversity is now our biggest fear<br/>
Now with our conversations tapped, and our differences exposed<br/>
How ya supposed to love your neighbour, with our minds and curtains
closed?<br/>
We used to worry &#8216;bout big brother<br/>
Now we got a big father and an even bigger mother</strong><br/>
<br/>
And still you believe, this aristocracy gives a fuck about you<br/>
They put the mock in democracy, and you swallowed every hook<br/>
The sad truth is, you'd rather follow the school into the net<br/>
&#8216;Cause swimming alone at sea, is not the kind of freedom that you
actually want<br/>
So go back to your crib, and suck on a tit<br/>
Bask in the warmth of your diaper, you're sitting in shit<br/>
And piss, while sucking on a giant pacifier<br/>
A country of adult infants, a legion of mental midgets<br/>
A country of adult infants, a country of adult infants<br/>
All regaining their unconsciousness<br/>
</tt>
&#8212;from the song <a href="http://www.nofxwiki.net/w/Lyrics:Regaining_Unconsciousness_%28song%29">Regaining Unconsciousness</a>, by <a href="http://www.nofx.org/">NOFX</a></p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/propaganda">propaganda</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/25/propaganda-makes-me-sick">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/25/propaganda-makes-me-sick">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-101">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/25/floating-point-in-elschemo">Floating point in ElSchemo</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-24T18:53:00+00:00">on Sunday, June 24</abbr>
<br class="clear" />
<div class="entry-content">
<p><em>NB: My Scheme interpreter is based on Jonathan Tang's <a href="http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/firststeps.html">Write Yourself a Scheme in 48 hours</a> Haskell tutorial. Not all of this makes sense outside that context, and the context of my previous posts on the subject.</em></p>
<p>My <a href="http://sami.samhuri.net/2007/06/14/more-scheming-with-haskell">scheme interpreter</a> has been christened ElSchemo, since it was sorely in need of a better name than "my Scheme interpreter". It's also seen far too much of my time and sports jazzy new features. I'll probably post the full code up here sooner or later, including my stdlib.scm and <a href="http://cubiclemuses.com/cm/blog/tags/Misp">misp</a> slightly modified to run with ElSchemo's limited vocabulary (namely the lack of <code>define-syntax</code>).</p>
<p>But that will be for another day, because today I want to talk about implementing floating point numbers, from parsing to operating on them.</p>
<div class="extended">
<p><a href="http://sami.samhuri.net/2007/6/25/floating-point-in-elschemo">Continue reading...</a></p>
</div>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/elschemo">elschemo</a>&nbsp;<a href="http://sami.samhuri.net/tags/haskell">haskell</a>&nbsp;<a href="http://sami.samhuri.net/tags/scheme">scheme</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/25/floating-point-in-elschemo">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/25/floating-point-in-elschemo">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-94">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/23/emacs-for-textmate-junkies">Emacs for TextMate junkies</a>
<span class="comment_count">6</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-23T02:17:00+00:00">on Saturday, June 23</abbr>
<br class="clear" />
<div class="entry-content">
<p><em>Update #1: What I first posted will take out your &lt; key by mistake (it's available via <code>C-q &lt;</code>), it has since been revised to Do The Right Thing.</em></p>
<p><em>Update #2: Thanks to an anonymouse[sic] commenter this code is a little cleaner.</em></p>
<p><em>Update #3: I should read the Emacs manual sometime, especially since I have it in dead-tree form. Check out <a href="http://www.gnu.org/software/emacs/manual/html_node/autotype/Inserting-Pairs.html">skeleton pairs</a> in the Emacs manual.</em></p>
<p>Despite my current infatuation with Emacs there are many reasons I started using TextMate, especially little time-savers that are very addictive. I'll talk about one of those features tonight. When you have text selected in TextMate and you hit say the <code>'</code> (single quote) then TextMate will surround the selected text with single quotes. The same goes for double quotes, parentheses, brackets, and braces. This little trick is one of my favourites so I had to come up with something similar in Emacs. It was easy since a <a href="http://osdir.com/ml/emacs.nxml.general/2005-08/msg00002.html">mailing list post</a> has a solution for surrounding the current region with tags, which served as a great starting point.</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">(defun surround-region-with-tag (tag-name beg end)<tt>
</tt> (interactive &quot;sTag name: \nr&quot;)<tt>
</tt> (save-excursion<tt>
</tt> (goto-char beg)<tt>
</tt> (insert &quot;&lt;&quot; tag-name &quot;&gt;&quot;)<tt>
</tt> (goto-char (+ end 2 (length tag-name)))<tt>
</tt> (insert &quot;&lt;/&quot; tag-name &quot;&gt;&quot;)))</pre></td>
</tr></table>
<p>With a little modification I now have the following in my ~/.emacs file:</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt>25<tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt>35<tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt>45<tt>
</tt>46<tt>
</tt>47<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">;; help out a TextMate junkie<tt>
</tt><tt>
</tt>(defun wrap-region (left right beg end)<tt>
</tt> &quot;Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right.&quot;<tt>
</tt> (interactive)<tt>
</tt> (save-excursion<tt>
</tt> (goto-char beg)<tt>
</tt> (insert left)<tt>
</tt> (goto-char (+ end (length left)))<tt>
</tt> (insert right)))<tt>
</tt><tt>
</tt>(defmacro wrap-region-with-function (left right)<tt>
</tt> &quot;Returns a function which, when called, will interactively `wrap-region-or-insert' using LEFT and RIGHT.&quot;<tt>
</tt> `(lambda () (interactive)<tt>
</tt> (wrap-region-or-insert ,left ,right)))<tt>
</tt><tt>
</tt>(defun wrap-region-with-tag-or-insert ()<tt>
</tt> (interactive)<tt>
</tt> (if (and mark-active transient-mark-mode)<tt>
</tt> (call-interactively 'wrap-region-with-tag)<tt>
</tt> (insert &quot;&lt;&quot;)))<tt>
</tt><tt>
</tt>(defun wrap-region-with-tag (tag beg end)<tt>
</tt> &quot;Wrap the region in the given HTML/XML tag using `wrap-region'. If any<tt>
</tt>attributes are specified then they are only included in the opening tag.&quot;<tt>
</tt> (interactive &quot;*sTag (including attributes): \nr&quot;)<tt>
</tt> (let* ((elems (split-string tag &quot; &quot;))<tt>
</tt> (tag-name (car elems))<tt>
</tt> (right (concat &quot;&lt;/&quot; tag-name &quot;&gt;&quot;)))<tt>
</tt> (if (= 1 (length elems))<tt>
</tt> (wrap-region (concat &quot;&lt;&quot; tag-name &quot;&gt;&quot;) right beg end)<tt>
</tt> (wrap-region (concat &quot;&lt;&quot; tag &quot;&gt;&quot;) right beg end))))<tt>
</tt><tt>
</tt>(defun wrap-region-or-insert (left right)<tt>
</tt> &quot;Wrap the region with `wrap-region' if an active region is marked, otherwise insert LEFT at point.&quot;<tt>
</tt> (interactive)<tt>
</tt> (if (and mark-active transient-mark-mode)<tt>
</tt> (wrap-region left right (region-beginning) (region-end))<tt>
</tt> (insert left)))<tt>
</tt><tt>
</tt>(global-set-key &quot;'&quot; (wrap-region-with-function &quot;'&quot; &quot;'&quot;))<tt>
</tt>(global-set-key &quot;\&quot;&quot; (wrap-region-with-function &quot;\&quot;&quot; &quot;\&quot;&quot;))<tt>
</tt>(global-set-key &quot;`&quot; (wrap-region-with-function &quot;`&quot; &quot;`&quot;))<tt>
</tt>(global-set-key &quot;(&quot; (wrap-region-with-function &quot;(&quot; &quot;)&quot;))<tt>
</tt>(global-set-key &quot;[&quot; (wrap-region-with-function &quot;[&quot; &quot;]&quot;))<tt>
</tt>(global-set-key &quot;{&quot; (wrap-region-with-function &quot;{&quot; &quot;}&quot;))<tt>
</tt>(global-set-key &quot;&lt;&quot; 'wrap-region-with-tag-or-insert) ;; I opted not to have a wrap-with-angle-brackets</pre></td>
</tr></table>
<p><a href="http://sami.samhuri.net/assets/2007/6/23/wrap-region.el" alt="wrap-region.el">Download wrap-region.el</a></p>
<p>That more or less sums up why I like Emacs so much. I wanted that functionality so I implemented it (barely! It was basically done for me), debugged it by immediately evaluating sexps and then trying it out, and then once it worked I reloaded my config and used the wanted feature. That's just awesome, and shows one strength of open source.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/emacs">emacs</a>&nbsp;<a href="http://sami.samhuri.net/tags/textmate">textmate</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/23/emacs-for-textmate-junkies">6 comments</a>,
<a href="http://sami.samhuri.net/2007/6/23/emacs-for-textmate-junkies">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-92">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/22/embrace-the-database">Embrace the database</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-22T10:14:00+00:00">on Friday, June 22</abbr>
<br class="clear" />
<div class="entry-content">
<p>If you drink the Rails koolaid you may have read the notorious <a href="http://www.loudthinking.com/arc/2005_09.html">single layer of cleverness</a> post by <a href="http://www.loudthinking.com/">DHH</a>. <em>[5th post on the archive page]</em> In a nutshell he states that it's better to have a single point of cleverness when it comes to business logic. The reasons for this include staying agile, staying in Ruby all the time, and being able to switch the back-end DB at any time. Put the logic in ActiveRecord and use the DB as a dumb data store, that is the Rails way. It's simple. It works. You don't need to be a DBA to be a Rails developer.</p>
<p><a href="http://www.stephenbartholomew.co.uk/">Stephen</a> created a Rails plugin called <a href="http://www.stephenbartholomew.co.uk/2007/6/22/dependent-raise">dependent-raise</a> which imitates a foreign key constraint inside of Rails. I want to try this out because I believe that data integrity is fairly important, but it's really starting to make me think about this single point of cleverness idea.</p>
<p>Are we not reinventing the wheel by employing methods such as this in our code? Capable DBs already do this sort of thing for us. I don't necessarily think it's bad to implement this sort of thing, but I think it's a symptom of NIH syndrome. Instead of reinventing this kind of thing why don't we embrace the DB as a semi-intelligent data store? The work has been done all we have to do is exploit it via Rails.</p>
<p>There are a few reasons that the Rails folks choose not to do so but perhaps some of them could be worked around. Adapting your solution as you progress and realise that things aren't exactly as you thought they were... I believe the word for that sort of thing is agility.</p>
<h3>Database agnosticism</h3>
<p>From SQLite to Oracle, just configure the connection, migrate, and run your app on any database. One of the biggest Rails myths that is backed by the Rails team themselves. It takes a fair amount of work to ensure that any significant app is fully agnostic. Sure you can develop on SQLite and deploy on MySQL without much trouble but there are significant diffirences between RDBMSs that will manifest themselves if you create an app that's more than a toy. Oh, you used finder_sql? Sorry but chances are your app is no longer DB agnostic. FAIL.</p>
<p><strong>Solution:</strong> Drop the lie. Tell people the truth. Theoretically, theory and practice are the same; in practice they are not. Be honest that it's <em>possible</em> to be DB-agnostic but can be a challenge. Under no circumstances should we shun something useful in the name of claiming to be DB-agnostic.</p>
<h3>Staying agile</h3>
<p>If we start making use of FK constraints then we'll have to make changes to both our DB and our code. This makes change more time-consuming and error-prone which means change is less likely to happen. This goes against the grain of an agile methodology. Or does it?</p>
<p><strong>Solution:</strong> Rails should use the features of the DB to keep data intact and fall back on an AR-only solution only if the DB doesn't support the operation. There doesn't need to be any duplication in logic rules either. If Rails could recognise a FK constraint that cascades on delete it could set up the <code>has_many :foos, :dependent =&gt; :destroy</code> relation for us. In fact I only see our code becoming DRYer (maybe even too DRY[1]).</p>
<h3>Staying in Ruby</h3>
<p>Using the DB from within Ruby is a solved problem. I don't see why this couldn't be extended to handle more of the DB as well. Use Ruby, but use it intelligently by embracing outside tools to get the job done.</p>
<p>Many relationships could be derived from constraints as people have pointed out before. There are benefits to using the features of a decent RDBMS, and in some cases I think that we might be losing by not making use of them. I am not saying we should move everything to the DB, I am saying that we should exploit the implemented and debugged capabilities of our RDBMSs the best we can while practicing the agile methods we know and love, all from within Ruby.</p>
<p>[1] I make liberal use of <a href="http://agilewebdevelopment.com/plugins/annotate_models">annotate_models</a> as it is.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/activerecord">activerecord</a>&nbsp;<a href="http://sami.samhuri.net/tags/rails">rails</a>&nbsp;<a href="http://sami.samhuri.net/tags/ruby">ruby</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/22/embrace-the-database">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/22/embrace-the-database">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-84">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/20/reinventing-the-wheel">Reinventing the wheel</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-20T16:27:00+00:00">on Wednesday, June 20</abbr>
<br class="clear" />
<div class="entry-content">
<p>Emacs is very impressive. I only felt lost and unproductive for minutes and now it seems natural to use and get around in. I've got <a href="http://sami.samhuri.net/2007/6/14/more-scheming-with-haskell">ElSchemo</a> set as the default scheme, and running inferior processes interactively is an absolute dream. My scheme doesn't have readline support (which bothers me to the point where I've thought about adding it just so I can use the thing) but when running it under Emacs there's absoutely no need for anything like that since I have the power of my editor when interacting with any program.</p>
<p>There has been a considerable amount of work done to aide in Rails development which makes Emacs especially comfortable for me. I now know why people have Emacs windows maximized on their screens. Because of its age Emacs is a handy window manager that basically eliminates the need for anything like <a href="http://en.wikipedia.org/wiki/GNU_Screen">GNU screen</a> or a window manager such as <a href="http://www.nongnu.org/ratpoison/">Rat poison</a> (which is great if you like screen), just maximize that Emacs "frame" or open one for each display and get to it. If you need a shell you just split the window and run your shell, when you're done you can easily switch back to your editing and your shell will wait in the background until you need it again. With rails-mode on I can run script/console (or switch back to it) with <code>C-c C-c s c</code>. My zsh alias for script/console is <code>sc</code> and I have other similarly succint ones for other stuff, so I took right to the shortcuts for all the handy things that I no longer have to switch applications to do:</p>
<ul>
<li><code>C-c C-c .</code> - Run the tests for this file. If I'm in a unit test it runs it, if I'm in the model it runs the corresponding unit tests.</li>
<li><code>C-c C-c w s</code> - Run the web server (script/server).</li>
<li><code>C-c C-c t</code> - Run tests. The last value entered is the default choice, and the options are analogous to the rake test:* tasks.</li>
<li>and so on...</li>
</ul>
<p>The Rails integration is simply stunning and I could go on all day about the mature indentation support, the Speedbar and what not, but I won't. I'm fairly sure that Emacs has taken the place of TextMate as my weapon of choice now, on all platforms. And after only 2 days!</p>
<p>Anyway, the point of all this was to mention the one thing that's missing: support for <a href="http://sami.samhuri.net/2006/2/22/intelligent-migration-snippets-0-1-for-textmate">intelligent snippets</a> which insert text at more than one point in the document (well, they appear to do so). I don't have any E-Lisp-fu to break out and solve the deficiency but if it ever bugs me enough I might try implementing it for Emacs one day. If they were useful to me outside of writing migrations I might have more incentive to do so, but I guess they aren't useful in normal editing situations (maybe I just haven't recognised the need).</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/emacs">emacs</a>&nbsp;<a href="http://sami.samhuri.net/tags/snippets">snippets</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/20/reinventing-the-wheel">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/20/reinventing-the-wheel">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-79">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/19/back-on-gentoo-trying-new-things">Back on Gentoo, trying new things</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-19T01:05:00+00:00">on Tuesday, June 19</abbr>
<br class="clear" />
<div class="entry-content">
<p>I started using my Gentoo box for development again and there are a few things about Linux I didn't realize I had been missing.</p>
<h3>Shell completion is awesome out of the box</h3>
<p>zsh has an impressive completion system but I just don't feel the urge to ever customize it extensively. I just use the basic completion stuff on OS X because it's easy. On Gentoo I have rake tasks and all sorts of other crap completed for me by including a few lines in my .zshrc (iirc a script does this automatically anyway). Generally Linux distros try to knit everything together nicely so you never even think about things like whether or not a package will have readline support, and default configs will be tweaked and enhanced beyond the official zsh package.</p>
<h3>Linux is stable. Really stable.</h3>
<p>While people bash Microsoft daily for tying the GUI layer to the kernel, Apple seems to get away with it scot-free. I don't know if it's caused by my external display hooked up to the dock, or the Prolific Firewire chip in my external disk enclosure but something causes the mysterious "music plays till the end of the song, mouse can be moved, but nothing works" bug now and then and all I can do is a hard reset.</p>
<p>On Linux I currently use Fluxbox so everything is rock solid and fast (except Firefox! ;-), but in the extremely rare event that shit does hit the fan usually only a single app will crash, though sometimes X (and hence many others) go with it. A <code>sudo /etc/init.d/gdm restart</code> fixes that. The only times I've had to hard reset Linux was because of a random bug (strangely similar to my MacBook bug) with Nvidia's driver with dual head setups. All this is pretty moot since Linux is generally just stable.</p>
<p>Those are 2 relatively small things but the added comfort they provide is very nice.</p>
<p>In the spirit of switching things up I'm going to forgo my usual routine of using gvim on Linux and try out emacs. I've been frustrated with vim's lack of a decent file browser and I've never much liked the tree plugin. Vim is a fantastic editor when it comes to navigating, slicing, and dicing text. After that it sort of falls flat though. After getting hooked on TextMate I have come to love integration with all sorts of external apps such as Subversion, rake, and the shell because it makes my work easier. Emacs seems to embrace that sort of philosophy and I'm more impressed with the efforts to integrate Rails development into Emacs than vim. I'm typing this post using the Textile mode for Emacs and the markup is rendered giving me a live preview of my post. It's not WYSIWYG like Typo's preview but it's still pretty damn cool. I think can get used to emacs.</p>
<p>I'm just waiting for a bunch of crap to compile - because I use Gentoo - and soon I'll have a Gtk-enabled Emacs to work in. If I can paste to and from Firefox then I'll be happy. I'll have to open this in vim or gedit to paste it into Firefox, funny!</p>
<p>I'm also going to try replacing a couple of desktop apps with web alternatives. I'm starting with 2 no-brainers: mail and feeds with Gmail and Google Reader. I never got into the Gmail craze and never really even used Gmail very much. After looking at the shortcuts I think I can get used to it. Seeing j/k for up/down is always nice. Thunderbird is ok but there isn't a mail client on Linux that I really like, except mutt. That played a part in my Gmail choice. I hadn't used G-Reader before either and it seems alright, but it'll be hard to beat NetNewsWire.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/emacs">emacs</a>&nbsp;<a href="http://sami.samhuri.net/tags/gentoo">gentoo</a>&nbsp;<a href="http://sami.samhuri.net/tags/linux">linux</a>&nbsp;<a href="http://sami.samhuri.net/tags/vim">vim</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/19/back-on-gentoo-trying-new-things">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/19/back-on-gentoo-trying-new-things">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-74">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/16/begging-the-question">Begging the question</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-15T18:49:00+00:00">on Friday, June 15</abbr>
<br class="clear" />
<div class="entry-content">
<p>I'm currently reading <a href="http://mitpress.mit.edu/sicp/full-text/book/book.html">SICP</a> since it's highly recommended by many people, available for free, and interesting. The fact that I have a little <a href="http://sami.samhuri.net/2007/6/14/more-scheming-with-haskell">Scheme interpreter</a> to play with makes it much more fun since I can add missing functionality to it as I progress through the book, thereby learning more Haskell in the process. Yay!</p>
<p>Anyway I was very pleased to see the only correct usage of the phrase "begs the question" I have seen in a while. It's a pet peeve of mine, but I have submitted myself to the fact that the phrase is so oft used to mean "begs for the following question to be asked..." that it may as well be re-defined. In its correct usage the sentence seems to hang there if you try to apply the commonly mistaken meaning to it. That's all very hazy so here's the usage in SICP (emphasis my own):</p>
<blockquote>As a case in point, consider the problem of computing square roots. We can define the square-root function as <img src="http://web.archive.org/web/20070629103138im_/http://sami.samhuri.net/files/ch1-Z-G-4.gif" alt="" />
<p>This describes a perfectly legitimate mathematical function. We could use it to recognize whether one number is the square root of another, or to derive facts about square roots in general. On the other hand, the definition does not describe a procedure. Indeed, it tells us almost nothing about how to actually find the square root of a given number. It will not help matters to rephrase this definition in pseudo-Lisp:</p>
<pre><code>(define (sqrt x)
(the y (and (>= y 0)
(= (square y) x))))</code></pre>
<strong>This only begs the question.</strong>
</blockquote>
<p>Begging the question is to assume what one is trying to prove (or here, define) and use that as the basis for a conclusion. Read the <a href="http://en.wikipedia.org/wiki/Begging_the_question">Wikipedia article</a> for a better definition and some nice examples.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/english">english</a>&nbsp;<a href="http://sami.samhuri.net/tags/life">life</a>&nbsp;<a href="http://sami.samhuri.net/tags/pedantry">pedantry</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/16/begging-the-question">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/16/begging-the-question">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-71">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/14/test-spec-on-rails-declared-awesome-just-one-catch">test/spec on rails declared awesome, just one catch</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-14T14:21:00+00:00">on Thursday, June 14</abbr>
<br class="clear" />
<div class="entry-content">
<p>This last week I've been getting to know <a href="http://chneukirchen.org/blog/archive/2007/01/announcing-test-spec-0-3-a-bdd-interface-for-test-unit.html">test/spec</a> via <a href="http://errtheblog.com/">err's</a> <a href="http://require.errtheblog.com/plugins/wiki/TestSpecRails">test/spec on rails</a> plugin. I have to say that I really dig this method of testing my code and I look forward to trying out some actual <a href="http://behaviour-driven.org/">BDD</a> in the future.</p>
<p>I did hit a little snag with functional testing though. The method of declaring which controller to use takes the form:</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">use_controller <span class="sy">:foo</span></pre></td>
</tr></table>
<p>and can be placed in the <code>setup</code> method, like so:</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># in test/functional/sessions_controller_test.rb</span><tt>
</tt><tt>
</tt>context <span class="s"><span class="dl">&quot;</span><span class="k">A guest</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt> fixtures <span class="sy">:users</span><tt>
</tt><tt>
</tt> setup <span class="r">do</span><tt>
</tt> use_controller <span class="sy">:sessions</span><tt>
</tt> <span class="r">end</span><tt>
</tt><tt>
</tt> specify <span class="s"><span class="dl">&quot;</span><span class="k">can login</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt> post <span class="sy">:create</span>, <span class="sy">:username</span> =&gt; <span class="s"><span class="dl">'</span><span class="k">sjs</span><span class="dl">'</span></span>, <span class="sy">:password</span> =&gt; <span class="s"><span class="dl">'</span><span class="k">blah</span><span class="dl">'</span></span><tt>
</tt> response.should.redirect_to user_url(users(<span class="sy">:sjs</span>))<tt>
</tt> ...<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span></pre></td>
</tr></table>
<p>This is great and the test will work. But let's say that I have another controller that guests can access:</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># in test/functional/foo_controller_test.rb</span><tt>
</tt><tt>
</tt>context <span class="s"><span class="dl">&quot;</span><span class="k">A guest</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt> setup <span class="r">do</span><tt>
</tt> use_controller <span class="sy">:foo</span><tt>
</tt> <span class="r">end</span><tt>
</tt><tt>
</tt> specify <span class="s"><span class="dl">&quot;</span><span class="k">can do foo stuff</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt> get <span class="sy">:fooriffic</span><tt>
</tt> status.should.be <span class="sy">:success</span><tt>
</tt> ...<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span></pre></td>
</tr></table>
<p>This test will pass on its own as well, which is what really tripped me up. When I ran my tests individually as I wrote them, they passed. When I ran <code>rake test:functionals</code> this morning and saw over a dozen failures and errors I was pretty alarmed. Then I looked at the errors and was thoroughly confused. Of course the action <strong>fooriffic</strong> can't be found in <strong>SessionsController</strong>, it lives in <strong>FooController</strong> and that's the controller I said to use! What gives?!</p>
<p>The problem is that test/spec only creates one context with a specific name, and re-uses that context on subsequent tests using the same context name. The various <code>setup</code> methods are all added to a list and each one is executed, not just the one in the same <code>context</code> block as the specs. I can see how that's useful, but for me right now it's just a hinderance as I'd have to uniquely name each context. "Another guest" just looks strange in a file by itself, and I want my tests to work with my brain not against it.</p>
<p>My solution was to just create a new context each time and re-use nothing. Only 2 lines in test/spec need to be changed to achieve this, but I'm not sure if what I'm doing is a bad idea. My tests pass and right now that's basically all I care about though.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/bdd">bdd</a>&nbsp;<a href="http://sami.samhuri.net/tags/rails">rails</a>&nbsp;<a href="http://sami.samhuri.net/tags/test/spec">test/spec</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/14/test-spec-on-rails-declared-awesome-just-one-catch">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/14/test-spec-on-rails-declared-awesome-just-one-catch">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-65">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/14/more-scheming-with-haskell">More Scheming with Haskell</a>
<span class="comment_count">2</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-14T01:09:00+00:00">on Thursday, June 14</abbr>
<br class="clear" />
<div class="entry-content">
<p>It's been a little while since I wrote about Haskell and the <a href="http://sami.samhuri.net/2007/5/3/a-scheme-parser-in-haskell-part-1">Scheme interpreter</a> I've been using to learn and play with both Haskell and Scheme. I finished the tutorial and got myself a working Scheme interpreter and indeed it has been fun to use it for trying out little things now and then. (Normally I would use Emacs or Dr. Scheme for that sort of thing.) There certainly are <a href="http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style">interesting things</a> to try floating around da intranet. And also things to read and learn from, such as <a href="http://cubiclemuses.com/cm/blog/tags/Misp">misp</a> (via <a href="http://moonbase.rydia.net/mental/blog/programming/misp-is-a-lisp">Moonbase</a>).</p>
<p><em>I'm going to describe two new features of my Scheme in this post. The second one is more interesting and was more fun to implement (cond).</em></p>
<h3>Parsing Scheme integers</h3>
<p>Last time I left off at parsing <a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.3.5">R5RS compliant numbers</a>, which is exercise 3.3.4 if you're following along the tutorial. Only integers in binary, octal, decimal, and hexadecimal are parsed right now. The syntaxes for those are <code>#b101010</code>, <code>#o52</code>, <code>42</code> (or <code>#d42</code>), and <code>#x2a</code>, respectively. To parse these we use the <code>readOct</code>, <code>readDec</code>, <code>readHex</code>, and <code>readInt</code> functions provided by the Numeric module, and import them thusly:</p>
<pre><code>import Numeric (readOct, readDec, readHex, readInt)</code></pre>
<p>In order to parse binary digits we need to write a few short functions to help us out. For some reason I couldn't find <code>binDigit</code>, <code>isBinDigit</code> and <code>readBin</code> in their respective modules but luckily they're trivial to implement. The first two are self-explanatory, as is the third if you look at the <a href="http://www.cse.ogi.edu/~diatchki/MonadTransformers/pfe.cgi?Numeric">implementation</a> of its relatives for larger bases. In a nutshell <code>readBin</code> says to: "read an integer in base 2, validating digits with <code>isBinDigit</code>."</p>
<pre><code>-- parse a binary digit, analagous to decDigit, octDigit, hexDigit
binDigit :: Parser Char
binDigit = oneOf "01"
-- analogous to isDigit, isOctdigit, isHexDigit
isBinDigit :: Char -> Bool
isBinDigit c = (c == '0' || c == '1')
-- analogous to readDec, readOct, readHex
readBin :: (Integral a) => ReadS a
readBin = readInt 2 isBinDigit digitToInt</code></pre>
<p>The next step is to augment <code>parseNumber</code> so that it can handle R5RS numbers in addition to regular decimal numbers. To refresh, the tutorial's <code>parseNumber</code> function looks like this:</p>
<pre><code>parseNumber :: Parser LispVal
parseNumber = liftM (Number . read) $ many1 digit</code></pre>
<p>Three more lines in this function will give us a decent starting point:</p>
<pre><code>parseNumber = do char '#'
base <- oneOf "bdox"
parseDigits base
<|> (many1 digit >>= return . Number . read)</code></pre>
<p>Translation: First look for an R5RS style base, and if found call <code>parseDigits</code> with the given base to do the dirty work. If that fails then fall back to parsing a boring old string of decimal digits.</p>
<p>That brings us to actually parsing the numbers. <code>parseDigits</code> is simple, but there might be a more Haskell-y way of doing this.</p>
<pre><code>-- Parse a string of digits in the given base.
parseDigits :: Char -> Parser LispVal
parseDigits base = do digits <- many1 d
return . Number . fst . head . f $ digits
where f = case base of
'b' -> readBin
'd' -> readDec
'o' -> readOct
'x' -> readHex
d = case base of
'b' -> binDigit
'd' -> digit
'o' -> octDigit
'x' -> hexDigit</code></pre>
<p>The trickiest part of all this was figuring out how to use the various <code>readFoo</code> functions properly. They return a list of pairs so <code>head</code> grabs the first pair and <code>fst</code> grabs the first element of the pair. Once I had that straight it was smooth sailing. Having done this, parsing R5RS characters (#\a, #\Z, #\?, ...) is a breeze so I won't bore you with that.</p>
<h3>The cond function</h3>
<p>It still takes me some time to knit together meaningful Haskell statements. Tonight I spent said time cobbling together an implementation of <a href="http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.1.5">cond</a> as a new special form. Have a look at the code. The explanation follows.</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">eval env (List (Atom &quot;cond&quot; : List (Atom &quot;else&quot; : exprs) : [])) =<tt>
</tt> liftM last $ mapM (eval env) exprs<tt>
</tt>eval env (List (Atom &quot;cond&quot; : List (pred : conseq) : rest)) = <tt>
</tt> do result &lt;- eval env $ pred<tt>
</tt> case result of<tt>
</tt> Bool False -&gt; case rest of<tt>
</tt> [] -&gt; return $ List []<tt>
</tt> _ -&gt; eval env $ List (Atom &quot;cond&quot; : rest)<tt>
</tt> _ -&gt; liftM last $ mapM (eval env) conseq</pre></td>
</tr></table>
<ul>
<li><b>Lines 1-2:</b> Handle <code>else</code> clauses by evaluating the given expression(s), returning the last result. It must come first or it's overlapped by the next pattern.</li>
<li><b>Line 3:</b> Evaluate a <code>cond</code> by splitting the first condition into <strong>predicate</strong> and <strong>consequence</strong>, tuck the remaining conditions into <code>rest</code> for later.</li>
<li><b>Line 4:</b> Evaluate <code>pred</code></li>
<li><b>Line 5:</b> and if the result is:</li>
<li><b>Line 6:</b> <code>#f</code> then look at the rest of the conditions.</li>
<li><b>Line 7:</b> If there are no more conditions return the empty list.</li>
<li><b>Line 8:</b> Otherwise call ourselves recursively with the remaining conditions.</li>
<li><b>Line 9:</b> Anything other than <code>#f</code> is considered true and causes <code>conseq</code> to be evaluated and returned. Like <code>else</code>, <code>conseq</code> can be a sequence of expressions.</li>
</ul>
<p>So far my Scheme weighs in at 621 lines, 200 more than the tutorial's final code listing. Hopefully I'll keep adding things on my TODO list and it will grow a little bit more. Now that I have <code>cond</code> it will be more fun to expand my stdlib.scm as well.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/coding">coding</a>&nbsp;<a href="http://sami.samhuri.net/tags/haskell">haskell</a>&nbsp;<a href="http://sami.samhuri.net/tags/scheme">scheme</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/14/more-scheming-with-haskell">2 comments</a>,
<a href="http://sami.samhuri.net/2007/6/14/more-scheming-with-haskell">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-61">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/9/so-long-typo-and-thanks-for-all-the-timeouts">so long typo (and thanks for all the timeouts)</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-09T01:01:00+00:00">on Saturday, June 09</abbr>
<br class="clear" />
<div class="entry-content">
<p>Well for just over a year Typo ran the show. I thought I had worked out most of the kinks with Typo and Dreamhost but the latest problem I ran into was pretty major. I couldn't post new articles. If the stars aligned perfectly and I sacrificed baby animals and virgins, every now and then I could get it to work. Ok, all I really had to do was refresh several dozen times, waiting 1 minute for it to timeout every time, but it sucked nonetheless.</p>
<p>Recently I had looked at converting Typo to Mephisto and it seemed pretty painless. I installed Mephisto and followed whatever instructions I found via Google and it all just worked, with one caveat. The Typo converter for Mephisto only supports Typo's schema version 56, while my Typo schema was at version 61. Rather than migrate backwards I brought Mephisto's Typo converter up to date instead. If you're interested, <a href="http://sami.samhuri.net/files/mephisto_converters-typo-schema_version_61.patch">download the patch</a>. The patch is relative to vendor/plugins, so patch accordingly.</p>
<p>After running that code snippet to fix my tags, I decided to completely ditch categories in favour of tags. I tagged each new Mephisto article with a tag for each Typo category it had previously belonged to. I fired up <code>RAILS_ENV=production script/console</code> and typed something similar to the following:</p>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span class="s"><span class="dl">'</span><span class="k">converters/base</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">converters/typo</span><span class="dl">'</span></span><tt>
</tt>articles = <span class="co">Typo</span>::<span class="co">Article</span>.find(<span class="sy">:all</span>).map {|a| [a, <span class="co">Article</span>.find_by_permalink(a.permalink)] }<tt>
</tt>articles.each <span class="r">do</span> |ta, ma|<tt>
</tt> <span class="r">next</span> <span class="r">if</span> ma.nil?<tt>
</tt> ma.tags &lt;&lt; <span class="co">Tag</span>.find_or_create(ta.categories.map(&amp;<span class="sy">:name</span>))<tt>
</tt><span class="r">end</span></pre></td>
</tr></table>
<p>When I say something similar I mean exactly that. I just typed that from memory so it may not work, or even be syntactically correct. If any permalinks changed then you'll have to manually add new tags corresponding to old Typo categories. The only case where this bit me was when I had edited the title of an article, in which case the new Mephisto permalink matched the new title while the Typo permalink matched the initial title, whatever it was.</p>
<p>I really dig Mephisto so far. It's snappier than Typo and the admin interface is slick. I followed the herd and went with the scribbish theme. Perhaps I'll get around to customizing it sometime, but who knows maybe I'll like a white background for a change.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/mephisto">mephisto</a>&nbsp;<a href="http://sami.samhuri.net/tags/typo">typo</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/9/so-long-typo-and-thanks-for-all-the-timeouts">0 comments</a>,
<a href="http://sami.samhuri.net/2007/6/9/so-long-typo-and-thanks-for-all-the-timeouts">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-60">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/6/9/301-moved-permanently">301 moved permanently</a>
<span class="comment_count">1</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-06-09T01:00:00+00:00">on Saturday, June 09</abbr>
<br class="clear" />
<div class="entry-content">
<p>Last weekend I moved out of the apartment I lived in for the last 3 1/2 years. Moving was a cinch thanks to a friend's garage, conveniently placed smack between my old place and the new one. Google maps tells me that I moved just under 3.4 km, which is 2.1 mi for the metric impaired, so it wasn't much of a move at all! My roommate and I live in the basement of a house split into 3 apartments. Our upstairs neighbours are friendly and seem pretty cool, except one lady upstairs seems a bit strange. It's a great place though and in the winter the wood stove fireplace is going to be awesome.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/life">life</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/6/9/301-moved-permanently">1 comment</a>,
<a href="http://sami.samhuri.net/2007/6/9/301-moved-permanently">permalink</a>
</li>
</ul>
</div>
<div class="hentry" id="article-59">
<h2 class="entry-title">
<a href="http://sami.samhuri.net/2007/5/26/finnish-court-rules-css-ineffective-at-protecting-dvds">Finnish court rules CSS ineffective at protecting DVDs</a>
<span class="comment_count">0</span>
</h2>
<div class="vcard">
Posted by <span class="fn">sjs</span>
</div>
<abbr class="published" title="2007-05-26T10:24:00+00:00">on Saturday, May 26</abbr>
<br class="clear" />
<div class="entry-content">
<p>It's nice to see people making sane calls on issues like this. <a href="http://arstechnica.com/index.ars">Ars</a> has a nice <a href="http://arstechnica.com/news.ars/post/20070525-finland-court-breaking-ineffective-copy-protection-is-permissible.html">summary</a> and there's also a <a href="http://www.turre.com/blog/?p=102">press release</a>.</p>
</div>
<ul class="meta">
<li>
Tags: <a href="http://sami.samhuri.net/tags/drm">drm</a>&nbsp;
</li>
<li>
Meta:
<a href="http://sami.samhuri.net/2007/5/26/finnish-court-rules-css-ineffective-at-protecting-dvds">0 comments</a>,
<a href="http://sami.samhuri.net/2007/5/26/finnish-court-rules-css-ineffective-at-protecting-dvds">permalink</a>
</li>
</ul>
</div>
</div>
<div id="sidebar">
<div class="sidebar-node">
<div id="search" class="search">
<form action="http://sami.samhuri.net/search" id="sform" method="get" name="sform">
<p><input type="text" id="q" name="q" value="" /></p>
</form>
</div>
</div>
<div class="sidebar-node">
<h3>Archives</h3>
<ul>
<li><a href="http://sami.samhuri.net/archives/2007/6">June 2007</a> (14)</li>
<li><a href="http://sami.samhuri.net/archives/2007/5">May 2007</a> (15)</li>
<li><a href="http://sami.samhuri.net/archives/2007/4">April 2007</a> (5)</li>
<li><a href="http://sami.samhuri.net/archives/2007/3">March 2007</a> (5)</li>
<li><a href="http://sami.samhuri.net/archives/2007/2">February 2007</a> (0)</li>
<li><a href="http://sami.samhuri.net/archives/2007/1">January 2007</a> (0)</li>
<li><a href="http://sami.samhuri.net/archives/2006/12">December 2006</a> (1)</li>
<li><a href="http://sami.samhuri.net/archives/2006/11">November 2006</a> (0)</li>
<li><a href="http://sami.samhuri.net/archives/2006/10">October 2006</a> (0)</li>
<li><a href="http://sami.samhuri.net/archives/2006/9">September 2006</a> (1)</li>
<li><a href="http://sami.samhuri.net/archives/2006/8">August 2006</a> (0)</li>
<li><a href="http://sami.samhuri.net/archives/2006/7">July 2006</a> (5)</li>
<li><a href="http://sami.samhuri.net/archives/2006/6">June 2006</a> (4)</li>
<li><a href="http://sami.samhuri.net/archives/2006/5">May 2006</a> (2)</li>
<li><a href="http://sami.samhuri.net/archives/2006/4">April 2006</a> (1)</li>
<li><a href="http://sami.samhuri.net/archives/2006/3">March 2006</a> (3)</li>
<li><a href="http://sami.samhuri.net/archives/2006/2">February 2006</a> (11)</li>
</ul>
</div>
<div class="sidebar-node">
<h3>Tags</h3>
<ul>
<li><a href="http://sami.samhuri.net/tags/activerecord">activerecord</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/amusement">amusement</a> (6)</li>
<li><a href="http://sami.samhuri.net/tags/apple">apple</a> (7)</li>
<li><a href="http://sami.samhuri.net/tags/bdd">bdd</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/bootcamp">bootcamp</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/buffalo">buffalo</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/bundle">bundle</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/cheat">cheat</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/coding">coding</a> (22)</li>
<li><a href="http://sami.samhuri.net/tags/cool">cool</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/coverflow">coverflow</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/crazy">crazy</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/digg">digg</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/drm">drm</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/dtrace">dtrace</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/elschemo">elschemo</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/emacs">emacs</a> (6)</li>
<li><a href="http://sami.samhuri.net/tags/english">english</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/extensions">extensions</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/firefox">firefox</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/framework">framework</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/funny">funny</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/fuse">fuse</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/games">games</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/gentoo">gentoo</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/german">german</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/haskell">haskell</a> (6)</li>
<li><a href="http://sami.samhuri.net/tags/inspirado">inspirado</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/iphone">iphone</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/itunes">itunes</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/i_laughed_i_cried">i_laughed_i_cried</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/keyboard">keyboard</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/life">life</a> (7)</li>
<li><a href="http://sami.samhuri.net/tags/linux">linux</a> (5)</li>
<li><a href="http://sami.samhuri.net/tags/mac%20os%20x">mac os x</a> (7)</li>
<li><a href="http://sami.samhuri.net/tags/mediawiki">mediawiki</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/mephisto">mephisto</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/migrations">migrations</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/munich">munich</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/mysql">mysql</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/networking">networking</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/parallels">parallels</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/pedantry">pedantry</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/photo">photo</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/php">php</a> (4)</li>
<li><a href="http://sami.samhuri.net/tags/propaganda">propaganda</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/python">python</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/rails">rails</a> (17)</li>
<li><a href="http://sami.samhuri.net/tags/rails%20on%20rules">rails on rules</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/regex">regex</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/regular%20expressions">regular expressions</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/rest">rest</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/rtfm">rtfm</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/ruby">ruby</a> (10)</li>
<li><a href="http://sami.samhuri.net/tags/sake">sake</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/scheme">scheme</a> (3)</li>
<li><a href="http://sami.samhuri.net/tags/school">school</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/secure%20associations">secure associations</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/seekport">seekport</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/snippets">snippets</a> (3)</li>
<li><a href="http://sami.samhuri.net/tags/tagify">tagify</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/technology">technology</a> (6)</li>
<li><a href="http://sami.samhuri.net/tags/test/spec">test/spec</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/textmate">textmate</a> (6)</li>
<li><a href="http://sami.samhuri.net/tags/typo">typo</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/ubuntu">ubuntu</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/usability">usability</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/userscript">userscript</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/vim">vim</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/wikipediafs">wikipediafs</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/windows">windows</a> (3)</li>
<li><a href="http://sami.samhuri.net/tags/work">work</a> (1)</li>
<li><a href="http://sami.samhuri.net/tags/zend">zend</a> (2)</li>
<li><a href="http://sami.samhuri.net/tags/zsh">zsh</a> (1)</li>
</ul>
</div>
<div class="sidebar-node">
<h3>Friends &amp; cool blogs</h3>
<ul>
<li><a href="http://jim.roepcke.com/">have browser, will travel</a></li>
<li><a href="http://cassandrahill.blogspot.com/">cj's chatter</a></li>
</ul>
</div>
<div class="sidebar-node">
<p><a href="http://twitter.com/_sjs">
<img src="http://web.archive.org/web/20070629103138im_/http://sami.samhuri.net/assets/2007/6/26/icon_twitter.png" alt="[t]" /> twitter</a></p>
</div>
<div class="sidebar-node">
<p><a href="http://mephistoblog.com/" class="powered"><img alt="mephisto-badge-tiny" src="http://web.archive.org/web/20070629103138im_/http://sami.samhuri.net/images/mephisto-badge-tiny.png" /></a></p>
</div>
</div>
<br style="clear:both;" />
</div>
<div id="footer">
<hr />
<p><a href="http://sami.samhuri.net/">sjs</a></p>
<ul>
<li>powered by <a href="http://mephistoblog.com/">Mephisto</a> /
styled with <a href="http://quotedprintable.com/pages/scribbish">scribbish</a></li>
</ul>
</div>
</div>
<script src="http://web.archive.org/web/20070629103138js_/http://www.google-analytics.com/urchin.js" type="text/javascript"> </script>
<script type="text/javascript"> _uacct = "UA-214054-3"; urchinTracker(); </script>
<script src="http://web.archive.org/web/20070629103138js_/http://feeds.feedburner.com/~s/sjs" type="text/javascript" charset="utf-8"></script>
</body>
</html>
<!--
FILE ARCHIVED ON 10:31:38 Jun 29, 2007 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 2:57:35 Aug 21, 2011.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->