<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>annealer</title>
 <link href="http://annealer.org/atom.xml" rel="self"/>
 <link href="http://annealer.org"/>
 <updated>2009-11-23T18:38:12-08:00</updated>
 <id>http://annealer.org</id>
 <author>
   <name>Gabriel Gironda</name>
   <email>gabriel.gironda@gmail.com</email>
 </author>

 
 <entry>
   <title>Zero to Compojure in a few easy steps</title>
   <link href="http://annealer.org/2009/11/23/zero-to-compojure-in-a-few-easy-steps.html"/>
   <updated>2009-11-23T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/11/23/zero-to-compojure-in-a-few-easy-steps</id>
   <content type="html">&lt;h2 id='step_one'&gt;Step One&lt;/h2&gt;

&lt;p&gt;Ensure you&amp;#8217;re running the latest RubyGems&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    gabriel@pinion:~/Code/GitHub$ sudo gem update --system
    Password:
    Updating RubyGems
    Nothing to update
    gabriel@pinion:~/Code/GitHub$ 
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='step_two'&gt;Step Two&lt;/h2&gt;

&lt;p&gt;Install JavaGems&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    gabriel@pinion:~/Code/GitHub$ gem install javagems
    WARNING:  Installing to ~/.gem since /opt/ruby-enterprise-edition/lib/ruby/gems/1.8 and
        /opt/ruby-enterprise-edition/bin aren&amp;#39;t both writable.
    Choosy clojurers choose Thumblemonks

    Remember to add ~/.javagem/java/bin to your PATH environment
    variable for maximum-JavaGems-fun-times.
    Successfully installed javagems-0.4.10
    1 gem installed
    Installing ri documentation for javagems-0.4.10...
    Installing RDoc documentation for javagems-0.4.10...
    gabriel@pinion:~/Code/GitHub$ 
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='step_three'&gt;Step Three&lt;/h2&gt;

&lt;p&gt;Install Compojure via JavaGems&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    gabriel@pinion:~/Code/GitHub$ javagem install compojure
    Successfully installed clojure-1.0.0
    Successfully installed clojure-contrib-1.0.0
    Successfully installed jetty-util-6.1.22
    Successfully installed servlet-api-2.5
    Successfully installed jetty-6.1.22
    Successfully installed commons-fileupload-1.2.1
    Successfully installed commons-codec-1.4
    Successfully installed commons-io-1.4
    Successfully installed compojure-0.3.1
    9 gems installed
    Installing ri documentation for clojure-1.0.0...
    Installing ri documentation for clojure-contrib-1.0.0...
    Installing ri documentation for jetty-util-6.1.22...
    Installing ri documentation for servlet-api-2.5...
    Installing ri documentation for jetty-6.1.22...
    Installing ri documentation for commons-fileupload-1.2.1...
    Installing ri documentation for commons-codec-1.4...
    Installing ri documentation for commons-io-1.4...
    Installing ri documentation for compojure-0.3.1...
    Installing RDoc documentation for clojure-1.0.0...
    Installing RDoc documentation for clojure-contrib-1.0.0...
    Installing RDoc documentation for jetty-util-6.1.22...
    Installing RDoc documentation for servlet-api-2.5...
    Installing RDoc documentation for jetty-6.1.22...
    Installing RDoc documentation for commons-fileupload-1.2.1...
    Installing RDoc documentation for commons-codec-1.4...
    Installing RDoc documentation for commons-io-1.4...
    Installing RDoc documentation for compojure-0.3.1...
    gabriel@pinion:~/Code/GitHub$ 
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='step_four'&gt;Step Four&lt;/h2&gt;

&lt;p&gt;Create a new project with Compojure specified in the Gemfile&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    gabriel@pinion:~/Code/GitHub$ mkdir compojure-example
    gabriel@pinion:~/Code/GitHub$ cd compojure-example/
    gabriel@pinion:~/Code/GitHub/compojure-example$ echo &amp;#39;gem &amp;quot;compojure&amp;quot;&amp;#39; &amp;gt; Gemfile
    gabriel@pinion:~/Code/GitHub/compojure-example$ 
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='step_five'&gt;Step Five&lt;/h2&gt;

&lt;p&gt;Run your sample app&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    gabriel@pinion:~/Code/GitHub/compojure-example$ cat hello.clj 
    (use &amp;#39;compojure)

    (defroutes my-app
      (GET &amp;quot;/&amp;quot;
        (html [:h1 &amp;quot;Hello World&amp;quot;]))
      (ANY &amp;quot;*&amp;quot;
        (page-not-found)))

    (run-server {:port 8080}
      &amp;quot;/*&amp;quot; (servlet my-app))

    gabriel@pinion:~/Code/GitHub/compojure-example$ jam clojure.main hello.clj
    2009-11-23 20:31:35.397:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
    clojure.proxy.javax.servlet.http.HttpServlet
    2009-11-23 20:31:35.493:INFO::jetty-6.1.x
    2009-11-23 20:31:35.996:INFO::Started SocketConnector@0.0.0.0:8080
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;All done!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>FFFUUU OPENSSL</title>
   <link href="http://annealer.org/2009/11/13/fffuuu-openssl.html"/>
   <updated>2009-11-13T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/11/13/fffuuu-openssl</id>
   <content type="html">&lt;img src='/images/fffuuu.jpg' alt='god fucking damn it' width='850' style='margin-left: auto; margin-right: auto; display: block; margin-bottom: 15px;' /&gt;
&lt;p&gt;Worst. Fucking. Part. Of dealing with OpenSSL. Seriously.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>open robots</title>
   <link href="http://annealer.org/2009/11/12/open-robots.html"/>
   <updated>2009-11-12T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/11/12/open-robots</id>
   <content type="html">&lt;img src='/images/rms-robots.jpg' alt='open robots' width='850' style='margin-left: auto; margin-right: auto; display: block;' /&gt;</content>
 </entry>
 
 <entry>
   <title>I do not think it means what you think it means.</title>
   <link href="http://annealer.org/2009/11/11/i-do-not-think-it-means-what-you-think-it-means.html"/>
   <updated>2009-11-11T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/11/11/i-do-not-think-it-means-what-you-think-it-means</id>
   <content type="html">&lt;p&gt;An &lt;a href='http://www.pcr-online.biz/features/328/Microsofts-new-vision'&gt;enlightening article&lt;/a&gt; by Andrew Wooden is making the rounds today, featuring some choice quotes from a certain Simon Aldous, who seems to be some kind of Microsoft marketing hotshot in the UK. I love when someone gives a soundbite that can be refuted by four seconds with Google and eight seconds of stepping back from the monitor, straightening your jacket, and beginning to perceive correctly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Is Windows 7 really a much more agile operating system, in terms of the specific uses it can be moulded to?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The interesting thing is, it’s basically the next version of Vista. Vista was a totally redesigned operating system from XP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let&amp;#8217;s take a trip down dictionary lane.&lt;/p&gt;
&lt;div style='background: white; padding: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; margin-bottom: 1em;'&gt;
  &lt;style type='text/css'&gt;
    p.dictp1 {margin: 0.0px 0.0px 23.0px 0.0px; text-align: center; line-height: 32.0px; font: 23.0px Baskerville, Georgia, serif; color: #666666}
    p.dictp2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Baskerville, Georgia, serif;}
    p.dictp3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px Baskerville, Georgia, serif;}
    p.dictp4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px Baskerville; min-height: 18.0px}
    p.dictp5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Hiragino Mincho Pro', Georgia, serif;}
    span.dicts1 {font: 19.0px Baskerville, Georgia, serif;}
    span.dicts2 {font: 17.0px Baskerville, Georgia, serif;}
    span.dicts3 {font: 13.0px 'Helvetica Neue', Helvetica, Arial;}
    span.dicts4 {font: 13.0px Baskerville, Georgia, serif;}
    span.dicts5 {font: 24.0px Baskerville, Georgia, serif;}
  &lt;/style&gt;
  
  &lt;p class='dictp1'&gt;&lt;i&gt;Oxford American Writer's Thesaurus&lt;/i&gt;&lt;/p&gt;
  &lt;p class='dictp2'&gt;totally&lt;/p&gt;
  &lt;p class='dictp3'&gt;adverb&lt;/p&gt;
  &lt;p class='dictp3'&gt;&lt;i&gt;the decor is totally pink&lt;/i&gt;: &lt;span class='dicts1'&gt;completely&lt;/span&gt;&lt;span class='dicts2'&gt;, &lt;/span&gt;entirely, wholly, thoroughly, fully, utterly, absolutely, perfectly, unreservedly, unconditionally, quite, altogether, downright; in every way, in every respect, one hundred percent, every inch, to the hilt; &lt;span class='dicts3'&gt;informal &lt;/span&gt;flat out, to the max.&lt;span class='dicts4'&gt; ANTONYMS &lt;/span&gt;partly.&lt;/p&gt;
  &lt;p class='dictp4'&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;p class='dictp1'&gt;&lt;i&gt;New Oxford American Dictionary&lt;/i&gt;&lt;/p&gt;
  &lt;p class='dictp5'&gt;&lt;span class='dicts5'&gt;totally&lt;/span&gt; |ˈtōtl-ē|&lt;/p&gt;
  &lt;p class='dictp3'&gt;adverb&lt;/p&gt;
  &lt;p class='dictp3'&gt;completely; absolutely &lt;i&gt;: the building was totally destroyed by the fire &lt;/i&gt;| [as submodifier ] &lt;i&gt;they came from totally different backgrounds.&lt;/i&gt;&lt;/p&gt;
  &lt;p class='dictp4'&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;p class='dictp5'&gt;&lt;span class='dicts5'&gt;redesign&lt;/span&gt; |ˌrēdiˈzīn|&lt;/p&gt;
  &lt;p class='dictp3'&gt;verb [ trans. ]&lt;/p&gt;
  &lt;p class='dictp3'&gt;design (something) again in a different way &lt;i&gt;: the front seats have been redesigned.&lt;/i&gt;&lt;/p&gt;
  &lt;p class='dictp3'&gt;noun&lt;/p&gt;
  &lt;p class='dictp3'&gt;the action or process of redesigning something.&lt;/p&gt;
  &lt;p class='dictp4'&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;p&gt;Now I don&amp;#8217;t know about you, but I wouldn&amp;#8217;t consider building an OS on top of a kernel that has its roots from circa 1989 a &amp;#8220;total redesign&amp;#8221;. I mean, if you&amp;#8217;re going to &lt;em&gt;be&lt;/em&gt; English, &lt;em&gt;speak&lt;/em&gt; English. There&amp;#8217;s nothing at all wrong with the fact it&amp;#8217;s built on the NT kernel, by the way. Just don&amp;#8217;t call it something it isn&amp;#8217;t.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ve improved upon Vista in that way. We’ve stripped out a lot of the code, we’ve made a lot of it much more efficient, it sits on a smaller footprint, it operates far more quickly, it’s far more agile and effective in terms of the calls it makes. I saw an article recently that described it as ‘Vista on steroids’, and in some ways you can absolutely relate to that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agile is my favourite new buzzword. I sure hope they agilely developed agile software that makes agile calls in their Department of Agility over at Agile Microsoft (the software company formerly known as Microsoft). What does he even mean? Did they hire an entire team to hand unroll loops and make function calls tail recursive? Dear Simon, if you&amp;#8217;re reading this, please quantify said statement. Otherwise I&amp;#8217;m adding it to the list of &amp;#8220;things I&amp;#8217;ve heard that make no sense&amp;#8221; right underneath the statement from a kid in grade school who told me he made a jetpack and car out of sticks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the things that people say an awful lot about the Apple Mac is that the OS is fantastic, that it’s very graphical and easy to use. What we’ve tried to do with Windows 7 – whether it’s traditional format or in a touch format – is create a Mac look and feel in terms of graphics. We’ve significantly improved the graphical user interface, but it’s built on that very stable core Vista technology, which is far more stable than the current Mac platform, for instance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because in the arena of popular operating systems, the one that&amp;#8217;s known for immense amounts of stability is Windows. Right. Mac OS X isn&amp;#8217;t perfect by far (hey thanks Snow Leopard bug that forces all my keyboard input to one application until I reboot the machine), but I don&amp;#8217;t recall the press around Vista being &amp;#8220;man this thing sure is ugly, but at least it&amp;#8217;s stable&amp;#8221;. Your FUD is embarrassing, and I see right through you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;So you’ve taken the style of the Mac platform and built it on the more solid foundations of Vista?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What the fuck, Andrew? I&amp;#8217;m not exactly a journalist, but I really don&amp;#8217;t think taking a contentious statement from the guy you&amp;#8217;re interviewing and then reinforcing it by reusing it in your own question is exactly a shining star of journalistic integrity. Up your game.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ve taken everything that’s good about Vista, along with the core infrastructure of the operating system, and we’ve made it faster and slimmed down the code to make it more effective.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You just said the good thing about Vista was the core infrastructure of the operating system. Essentially the same statement was made twice. Also, please quantify the usage of the term &amp;#8220;effective&amp;#8221;, in five hundred words or less. I don&amp;#8217;t know what you mean by &amp;#8220;effective&amp;#8221;. You&amp;#8217;re throwing words out there like a malfunctioning Speak and Spell. Forming coherent sentences doesn&amp;#8217;t work like that, unfortunately. I&amp;#8217;m sorry.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ve also tried to listen to what customers want in terms of a much slicker user interface and the ability to engage with it far more intuitively. That’s the product that we’re delivering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wish they&amp;#8217;d fire this dude and deliver a new marketing guy an interviewer can engage with far more intuitively (and &amp;#8220;effectively&amp;#8221;). Is this seriously the best you can come up with, Microsoft? I don&amp;#8217;t even mean Windows 7, I&amp;#8217;m talking about the total stooge you sent out to shill it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Thumbs Down for Your Shitty Ivory Tower</title>
   <link href="http://annealer.org/2009/11/10/thumbs-down-for-your-shitty-ivory-tower.html"/>
   <updated>2009-11-10T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/11/10/thumbs-down-for-your-shitty-ivory-tower</id>
   <content type="html">&lt;p&gt;I recently stumbled into the land of Clojure and was subsequently shown &lt;a href='http://www.loper-os.org/?p=42' title='this article sucks'&gt;a delightful demonstration of looking down your nose&lt;/a&gt; in its peak form. I haven&amp;#8217;t seen pointless elitism on this grand a scale since&amp;#8230; well&amp;#8230; the last time I started poking around a language badly in need of one of those giant needles from Pulp Fiction to the chest because hardly anyone was using it for anything useful ever.&lt;/p&gt;

&lt;p&gt;I quote, from this paragon of snobbery:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I find Clojure revolting.&lt;/p&gt;

&lt;p&gt;It is the most explicit to date abandonment of the age-old Lispers’ Dream, “Lisp All The Way Down.” Clojure is the antithesis of the Lisp Machine. Instead of a crystalline pyramid of comprehensible mutually-interlocking concepts, behind every Clojure primitive there lurks Black Magic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That&amp;#8217;s great. I&amp;#8217;m happy you find it to be the antithesis of a hardware/software platform that has been dead since the 1980s. Please write another post once you find the antithesis of the following platforms: IRIX on SGI MIPS hardware, Smalltalk on Xerox Alto hardware, NeXTSTEP on a NeXTcube. If you could also take into account the subsequent death (Mac OS X notwithstanding) of each of these platforms despite their respective amounts of technical superiority over whatever else existed at the time, that would be great too. In a follow-up post, please also explain the black magic behind generating C, JVM, or .NET bytecode in &lt;a href='http://en.wikipedia.org/wiki/Bigloo'&gt;Bigloo Scheme&lt;/a&gt; and the contents of &lt;code&gt;eval.c&lt;/code&gt; in MzScheme. That would be aces. Being in line with your &amp;#8220;pure-Lisp&amp;#8221; worldview, as they&amp;#8217;re implementations of Scheme, resolving this apparent cognitive dissonance should be easy enough.&lt;/p&gt;

&lt;p&gt;Continuing down this path of pompous self righteousness&amp;#8230;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Clojure user who is missing some routine or other will run crying to Java for help, rather than implementing the feature himself correctly - that is, as a natural part of the entire language, built on the same concepts. Clojure pisses on everything I’ve ever loved about Lisp. It rejects even what little consistency and intellectual rigor there is to be found in an abomination like Common Lisp.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Heavens no. How dare someone implement a feature in another lanGGGGGGGGG-oh-god-code-snippets&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='cm'&gt;/* network.c from MzScheme */&lt;/span&gt;
&lt;span class='cp'&gt;    # include &amp;lt;netinet/in.h&amp;gt;&lt;/span&gt;
&lt;span class='cp'&gt;    # include &amp;lt;netdb.h&amp;gt;&lt;/span&gt;
&lt;span class='cp'&gt;    # include &amp;lt;sys/socket.h&amp;gt;&lt;/span&gt;
&lt;span class='cp'&gt;    # include &amp;lt;fcntl.h&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;isweartogodihadapointheeeeeeeee@#@@@#%%^^!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='cm'&gt;/* strftime.c from GNU Guile */&lt;/span&gt;
    &lt;span class='cm'&gt;/* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2009 Free Software&lt;/span&gt;
&lt;span class='cm'&gt;       Foundation, Inc.&lt;/span&gt;

&lt;span class='cm'&gt;       NOTE: The canonical source of this file is maintained with the GNU C Library. &amp;lt;-- HEY LOOK AT THAT&lt;/span&gt;
&lt;span class='cm'&gt;       Bugs can be reported to bug-glibc@prep.ai.mit.edu. */&lt;/span&gt;
    &lt;span class='cm'&gt;/* SNIP */&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;reallyabouttogetbackontrackiprZZZZZZZZZZZZZCARRIERLOST&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='cm'&gt;/* re.c from the regexp implementation for TinyScheme */&lt;/span&gt;
    &lt;span class='cm'&gt;/* re.c */&lt;/span&gt;
    &lt;span class='cm'&gt;/* Henry Spencer&amp;#39;s implementation of Regular Expressions,&lt;/span&gt;
&lt;span class='cm'&gt;       used for TinyScheme */&lt;/span&gt;
    &lt;span class='cm'&gt;/* Refurbished by Stephen Gildea */&lt;/span&gt;
&lt;span class='cp'&gt;    #include &amp;quot;regex.h&amp;quot;&lt;/span&gt;
&lt;span class='cp'&gt;    #include &amp;quot;scheme.h&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Holy shit. My mind has been blown. Three separate Scheme implementations, re-using C code and even implementing parts of the language in C? Heavens no! Please Lord, reach down from the heavens and pinch my bottom so I KNOW THAT I&amp;#8217;M DREAMING. Hey guy, when you&amp;#8217;re done reinventing the wheel, I have this mousetrap that needs fixing. Copious amounts of sarcasm aside, using another language for help isn&amp;#8217;t called &amp;#8220;running crying&amp;#8221;, in most places it&amp;#8217;s called &amp;#8220;pragmatism&amp;#8221; and, it lets you do things like &amp;#8220;write software to solve the task at hand&amp;#8221; rather than &amp;#8220;write three socket implementations and a regexp library because you just LOVE shaving yaks&amp;#8221;. If you could let the maintainers of every single Scheme implementation know they&amp;#8217;re doing it wrong every time they drop down to C, that would be great, thanks.&lt;/p&gt;

&lt;p&gt;Carrying on with indestructible resolve and I stiff upper lip, I bring you&amp;#8230;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Clojure is the False Lisp, which Reeketh of the Cube Farm. A Lisp unworthy of the name; one which encourages users to pepper their code with calls to opaque routines having no underlying Lispiness. A Lisp which barfs Java stack traces. It promotes - no, mandates - the use of undigestable foreign matter in Lisp code: primitives on which you cannot pop the hood to reveal intelligible innards.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I Love The Capitalisation Here. Heh. You Peon. In Your Cube Farm. Come Back To Me When You Code In A Real Language, Newbie. Heh. I Bet You Don&amp;#8217;t Even Know APL. Dumbass. If only &lt;a href='http://github.com/richhickey/clojure/tree/master/src/clj/clojure/'&gt;Clojure were some kind of open source project&lt;/a&gt; with &lt;a href='http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj'&gt;large amounts of the language&lt;/a&gt; implemented in Clojure itself. If only the parts that weren&amp;#8217;t in Clojure were &lt;a href='http://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Symbol.java'&gt;implemented in some kind of higher level language than C&lt;/a&gt; so that they were easily comprehensible by most humans (note: this is in no shape, way, or form an endorsement of Java in general). Oh shit, those all hold true? My mistake.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don’t care if everybody really is more productive in Clojure than in Common Lisp. The latter is not my standard of comparison (Symbolics Genera, the state of the art, is. Or, if you want something that is distinctly inferior but is currently available on the market: Mathematica.) Clojure is the gutted and zombie-reanimated corpse of a dream.&lt;/p&gt;

&lt;p&gt;The cult of Good Enough which seems to pervade all of modern computing has finally chewed its way through to the Lisp community, with Clojure as the result. I am tired of this abomination being hailed as the future of Lisp. Aficionados of real Lisps, such as myself, will keep hoping, dreaming, and working on systems which do not betray the original virtues of the language.&lt;/p&gt;

&lt;p&gt;Symbolics Genera remains the gold standard of programming systems. Though largely forgotten, it can never be un-created. My standard of comparison for any technology will always be everything previously achieved by mankind, rather than what is available on the market today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok. I think I&amp;#8217;ve spotted the core of our mutual disconnect here. I&amp;#8217;d like to be productive in Lisp and be able to write usable and deployable software in it, whereas you want a fucking DeLorean so we can flux-capacitor our way back to 1985 and kill Bill Joy then sell a bunch of expensive Symbolics hardware. I see. I think you should start a club with some of the more hardcore (disclaimer: I fucking love Smalltalk) Smalltalk guys and you can have a collective circlejerk about how great your closed ecosystem of writing custom version control systems and deployment solutions is. In the meantime, I&amp;#8217;ll be busy with Clojure and GNU Smalltalk and getting things done. Thanks! Send me a postcard from the ivory tower some time, I hear the view is spectacular, but the company leaves something to be desired.&lt;/p&gt;

&lt;p&gt;My point here is this: Clojure is a young language. The last thing it needs is the Lisp-elitists stomping all over it because it doesn&amp;#8217;t meet their standards of purity (which can only be met by running on dead hardware). Hopefully, the fact that it&amp;#8217;s actually usable for writing every-day software will let it overcome the naysayers. You aren&amp;#8217;t really helping further the cause of Lisp in general by scaring away newcomers with a lot of chest-thumping and quoting of the nerd version of the &lt;a href='http://en.wikipedia.org/wiki/Reinheitsgebot'&gt;Reinheitsgebot&lt;/a&gt;. If Clojure were my first exposure to Lisp, and I read that blog post, I&amp;#8217;d probably stay the fuck away. Not based on any technical pros/cons, but more because I&amp;#8217;d think the Lisp community is a bunch of dicks (which it isn&amp;#8217;t, for the most part).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>GitHub fork of Vlad the Deployer with better Git support</title>
   <link href="http://annealer.org/2009/01/08/better-git-support-in-vlad-the-deployer.html"/>
   <updated>2009-01-08T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/01/08/better-git-support-in-vlad-the-deployer</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Do you use Git?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do you use Vlad the Deployer?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do you use Capistrano but don&amp;#8217;t actually like it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then my &lt;a href='http://github.com/gabrielg/vlad/tree/master'&gt;GitHub fork&lt;/a&gt; of Vlad the Deployer may be for you.&lt;/p&gt;

&lt;p&gt;The current Git support in Vlad is lacking in a few ways, namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It performs a new clone of the repository every deploy&lt;/li&gt;

&lt;li&gt;It lacks submodule support&lt;/li&gt;

&lt;li&gt;It uses git-archive to export the repository, which also lacks submodule support&lt;/li&gt;

&lt;li&gt;It unnecessarily creates branches in the repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With some help from coworkers, the support in my fork has been much improved. Highlights are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One clone on initial setup&lt;/li&gt;

&lt;li&gt;Submodule support&lt;/li&gt;

&lt;li&gt;Avoids git-archive so submodules are exported correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&amp;#8217;re interested in Vlad in general, check out &lt;a href='http://hitsquad.rubyforge.org/vlad/files/doco/getting_started_txt.html'&gt;the getting started guide&lt;/a&gt; and the &lt;a href='http://rubyhitsquad.com/Vlad_the_Deployer.html'&gt;website&lt;/a&gt; - it&amp;#8217;s a much simpler rake-based alternative to using Capistrano that solves 80% of common deployment issues. Since it&amp;#8217;s rake-based, it&amp;#8217;s easy to add the other 20% you may need.&lt;/p&gt;

&lt;p&gt;My fork is available as a Gem on GitHub, so if GitHub is in your gem sources list, a &lt;code&gt;gem install gabrielg-vlad&lt;/code&gt; is all that&amp;#8217;s necessary.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Fast and easy method protocols in Ruby</title>
   <link href="http://annealer.org/2009/01/02/fast-and-easy-protocols-in-ruby.html"/>
   <updated>2009-01-02T00:00:00-08:00</updated>
   <id>http://annealer.org/2009/01/02/fast-and-easy-protocols-in-ruby</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.squeak.org/'&gt;Squeak&lt;/a&gt; has a concept of &amp;#8220;protocols&amp;#8221;, in which you can group related methods. &lt;a href='http://www.sneer.org'&gt;Jason&lt;/a&gt; wanted me to throw together a protocol implementation in Ruby. Here&amp;#8217;s a fast and easy implementation that I&amp;#8217;ll probably never use in production code.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Module&lt;/span&gt;
      &lt;span class='vi'&gt;@protocols&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;protocols&lt;/span&gt;
        &lt;span class='vi'&gt;@protocols&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='nb'&gt;ancestors&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='nb'&gt;ancestors&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dup&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='c1'&gt;# def add_to_protocol&lt;/span&gt;
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;protocol&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;protocol_name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;raise&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;A block is required&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='nb'&gt;block_given?&lt;/span&gt;
        &lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;protocol_name&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;
        &lt;span class='n'&gt;original_method_added&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;method&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:method_added&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;unbind&lt;/span&gt;
        &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:define_method&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:method_added&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;method_name&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
          &lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;protocol_name&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;method_name&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;yield&lt;/span&gt;
      &lt;span class='k'&gt;ensure&lt;/span&gt;
        &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;remove_method&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:method_added&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='n'&gt;original_method_added&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vg'&gt;$0&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vg'&gt;$PROGRAM_NAME&lt;/span&gt;  
    &lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;test/unit&amp;#39;&lt;/span&gt;

    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ProtocolTest&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Test&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Unit&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;TestCase&lt;/span&gt;
  
      &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;TestClass&lt;/span&gt;
    
        &lt;span class='n'&gt;protocol&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;setters&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;bar&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;  
    
        &lt;span class='n'&gt;protocol&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;getters&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;bar&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
   
        &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;foobarbaz&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
    
        &lt;span class='n'&gt;protocol&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;getters&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;foo&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
    
      &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# TestClass&lt;/span&gt;
    
      &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SonOfTestClass&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_should_have_bar_equals_in_setters_protocol&lt;/span&gt;
        &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;bar=&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;setters&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_should_have_bar_and_foo_in_getters_protocol&lt;/span&gt;
        &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;getters&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_foobarbaz_shouldnt_be_any_any_protocols&lt;/span&gt;
        &lt;span class='n'&gt;assert&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;values&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flatten&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;uniq&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;include?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;foobarbaz&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_testclass_and_sonoftestclass_should_have_same_protocols_and_different_protocol_variables&lt;/span&gt;
        &lt;span class='n'&gt;assert&lt;/span&gt; &lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;object_id&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='no'&gt;SonOfTestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;object_id&lt;/span&gt;
        &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='no'&gt;TestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;values&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flatten&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;SonOfTestClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;protocols&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;values&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flatten&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Interesting Rails commits, Volume #1</title>
   <link href="http://annealer.org/2008/12/29/interesting-rails-commits-vol-1.html"/>
   <updated>2008-12-29T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/29/interesting-rails-commits-vol-1</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a rundown of recent Rails commits I&amp;#8217;ve found of interest. I&amp;#8217;ll probably be continuing this series of posts until either people stop committing to Rails or I get bored of doing it, which ever one comes first. No fixed schedule, just when I think there&amp;#8217;s enough interesting commits to post about.&lt;/p&gt;

&lt;h2 id='multiple_condition_support_in_activesupportcallbacks'&gt;Multiple condition support in ActiveSupport::Callbacks&lt;/h2&gt;

&lt;p&gt;As of &lt;a href='http://github.com/rails/rails/commit/1e45818a622405e720a4529795f8be2f11660361'&gt;commit 1e45818a622405e720a4529795f8be2f11660361&lt;/a&gt;, &lt;code&gt;ActiveSupport::Callbacks&lt;/code&gt; now supports multiple conditions. What this means is you can now write code like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    
    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Hero&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
      &lt;span class='n'&gt;before_save&lt;/span&gt; &lt;span class='ss'&gt;:add_awesome_robert_fripp_feedback&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:if&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:bowie_original&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Proc&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;not_a_shitty_cover?&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='n'&gt;before_save&lt;/span&gt; &lt;span class='ss'&gt;:tony_viscontiize&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:unless&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:not_a_bowie_original&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Proc&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|!&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;not_a_shitty_cover?&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the first callback will only run if both the method &lt;code&gt;bowie_original&lt;/code&gt; and the &lt;code&gt;Proc&lt;/code&gt; that checks for &lt;code&gt;not_a_shitty_cover&lt;/code&gt; return &lt;code&gt;true&lt;/code&gt;. The second callback will run unless &lt;em&gt;any&lt;/em&gt; of the specified conditions return &lt;code&gt;true&lt;/code&gt; - that is, &lt;code&gt;tony_viscontiize&lt;/code&gt; will get called unless &lt;code&gt;not_a_bowie_original&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; or the given &lt;code&gt;Proc&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;. Both must be &lt;code&gt;false&lt;/code&gt; for it to be called.&lt;/p&gt;

&lt;p&gt;Remember, these are in &lt;code&gt;ActiveSupport::Callbacks&lt;/code&gt;, so you can make use of this functionality in your own code that uses the module, &lt;code&gt;ActiveRecord&lt;/code&gt;, or anywhere else in Rails using it.&lt;/p&gt;

&lt;h2 id='dynamic_scopes_in_activerecord'&gt;Dynamic scopes in ActiveRecord&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://github.com/rails/rails/commit/66ee5890c5f21995b7fe0c486547f1287afe2b55'&gt;Commit 66ee5890c5f21995b7fe0c486547f1287afe2b55&lt;/a&gt; adds dynamic scopes to &lt;code&gt;ActiveRecord&lt;/code&gt;. Much like the &lt;a href='http://api.rubyonrails.org/classes/ActiveRecord/Base.html'&gt;dynamic finders&lt;/a&gt;, you can now create dynamic scopes.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    
    &lt;span class='c1'&gt;# This new call:&lt;/span&gt;
    &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scoped_by_user_name&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;joe&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;all&lt;/span&gt; 
    
    &lt;span class='c1'&gt;# Is equivalent to this named scope:&lt;/span&gt;
    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt;
      &lt;span class='n'&gt;named_scope&lt;/span&gt; &lt;span class='ss'&gt;:user_name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;lambda&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; 
        &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:conditions&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;user_name = ?&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; 
      &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you haven&amp;#8217;t yet checked out &lt;a href='http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M001906'&gt;named scope&lt;/a&gt;, take a look at it. It&amp;#8217;s useful for moving a lot of code back into the class it belongs in, outside of things like &lt;code&gt;AssociationProxy&lt;/code&gt; extensions.&lt;/p&gt;

&lt;h2 id='http_digest_authentication'&gt;HTTP Digest authentication&lt;/h2&gt;

&lt;p&gt;Finally, &lt;a href='http://github.com/rails/rails/commit/45dee3842d68359a189fe7c0729359bd5a905ea4'&gt;commit 45dee3842d68359a189fe7c0729359bd5a905ea4&lt;/a&gt; adds &lt;a href='http://en.wikipedia.org/wiki/Digest_access_authentication'&gt;HTTP Digest&lt;/a&gt; authentication support to &lt;code&gt;ActionController&lt;/code&gt;, alongside the existing support for &lt;a href='http://en.wikipedia.org/wiki/Basic_access_authentication'&gt;HTTP Basic&lt;/a&gt; authentication. A common usage case could look like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;  
    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;TrackController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
      &lt;span class='n'&gt;before_filter&lt;/span&gt; &lt;span class='ss'&gt;:authenticate&lt;/span&gt;
      
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;index&lt;/span&gt;
        &lt;span class='n'&gt;render&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      
    &lt;span class='kp'&gt;private&lt;/span&gt;
    
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;authenticate&lt;/span&gt;
        &lt;span class='c1'&gt;# This block must return the expected password&lt;/span&gt;
        &lt;span class='n'&gt;authenticate_or_request_with_http_digest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Secure Area&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;user_name&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;  
          &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_by_username&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user_name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;password&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      
    &lt;span class='k'&gt;end&lt;/span&gt;
    
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A change from Basic authentication is that you must be able to get at the expected password and return it as the result of the block. So if you&amp;#8217;re salting and hashing passwords in the database, there&amp;#8217;s a great chance Digest authentication isn&amp;#8217;t going to work for you. If you&amp;#8217;re encrypting them instead and are already using Basic authentication, consider looking at Digest authentication for a slightly more secure mechanism of checking credentials.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Jekyll tip for rendering individual posts</title>
   <link href="http://annealer.org/2008/12/28/jekyll-layout-tip.html"/>
   <updated>2008-12-28T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/28/jekyll-layout-tip</id>
   <content type="html">&lt;p&gt;When rendering individual posts, your layout may look something like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;meta&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;h3&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class='na'&gt;href=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;{ {page.url|xml_escape} }&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;{ {page.title|xml_escape} }&lt;span class='nt'&gt;&amp;lt;/a&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;p&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Written on { {page.date | date: &amp;quot;%A, %B %d, %Y&amp;quot;} }&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;page.content&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        { {page.content} }
      &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;While everything else is done via the &lt;code&gt;page&lt;/code&gt; variable (&lt;code&gt;page.title&lt;/code&gt; for example), the actual post content should be rendered just by using the &lt;code&gt;content&lt;/code&gt; variable, and not &lt;code&gt;page.content&lt;/code&gt; as I previously used, making the layout look closer to:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;meta&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;h3&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class='na'&gt;href=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;{ {page.url|xml_escape} }&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;{ {page.title|xml_escape} }&lt;span class='nt'&gt;&amp;lt;/a&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;p&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Written on { {page.date | date: &amp;quot;%A, %B %d, %Y&amp;quot;} }&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;page.content&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        { {content} }
      &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you use &lt;code&gt;page.content&lt;/code&gt; you&amp;#8217;ll be scratching your head at why your posts are rendering as un-marked up and un-syntax-highlighted text. As a side note, if anyone could figure out how to escape Liquid tags so double-curly-braces aren&amp;#8217;t interpreted, that&amp;#8217;d be swell.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ghetto contexts in Rails tests</title>
   <link href="http://annealer.org/2008/12/26/patching-rails-and-ghetto-contexts.html"/>
   <updated>2008-12-26T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/26/patching-rails-and-ghetto-contexts</id>
   <content type="html">&lt;p&gt;One thing I really miss when I&amp;#8217;m working in a &lt;a href='http://www.thoughtbot.com/projects/shoulda'&gt;Shoulda&lt;/a&gt;-less environment is contexts in my tests. Contexts let me properly arrange my tests in a way that makes sense, clean up my setup methods, and write/generate test names that are easily readable and immediately convey what&amp;#8217;s meant to be tested.&lt;/p&gt;

&lt;p&gt;Recently I &lt;a href='http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1639'&gt;submitted a Rails patch&lt;/a&gt; to allow for an &lt;code&gt;:on&lt;/code&gt; option in &lt;code&gt;ActiveRecord::Observer&lt;/code&gt;. As an example, I wanted to be able to write code like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;HappenableObserver&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Observer&lt;/span&gt;
      &lt;span class='n'&gt;observe&lt;/span&gt; &lt;span class='ss'&gt;:comment&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:photo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:on&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:after_create&lt;/span&gt;
      &lt;span class='n'&gt;observe&lt;/span&gt; &lt;span class='ss'&gt;:post&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:on&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:after_create&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_update&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='n'&gt;observe&lt;/span&gt; &lt;span class='ss'&gt;:event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:participation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:on&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:after_create&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_destroy&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  
      &lt;span class='c1'&gt;# Actual callback methods omitted....&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The intent being that the &lt;code&gt;after_create&lt;/code&gt; is the only one that gets fired for &lt;code&gt;Comment&lt;/code&gt; and &lt;code&gt;Photo&lt;/code&gt;, &lt;code&gt;Post&lt;/code&gt; gets &lt;code&gt;after_create&lt;/code&gt; and &lt;code&gt;after_update&lt;/code&gt;, etcetera, the &lt;code&gt;HappenableObserver&lt;/code&gt; being a kind of activity feed creator. Right now, without doing it by hand or creating separate observers, this isn&amp;#8217;t possible in &lt;code&gt;ActiveRecord::Observer&lt;/code&gt;. When writing the patch, I ran into places where I needed an object, and didn&amp;#8217;t actually need a different instance of it for every test method. Enter, ghetto-contexts. Here&amp;#8217;s an excerpt from my tests for the patch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ObserverTest&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;TestCase&lt;/span&gt;
  
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;setup&lt;/span&gt;
        &lt;span class='vi'&gt;@observer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;ActivityObserver&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
  
      &lt;span class='nb'&gt;lambda&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='c1'&gt;# with topic &lt;/span&gt;
        &lt;span class='n'&gt;topic&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    
        &lt;span class='nb'&gt;test&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should observe after_create on Topic&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='vi'&gt;@observer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expects&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:after_create&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:notify&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_create&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;

        &lt;span class='nb'&gt;test&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should observe before_destroy on Topic&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; 
          &lt;span class='vi'&gt;@observer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expects&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:before_destroy&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:notify&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:before_destroy&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
  
        &lt;span class='nb'&gt;test&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should observe before_save on Topic&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='vi'&gt;@observer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expects&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:before_save&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:notify&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:before_save&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
  
        &lt;span class='nb'&gt;test&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should ignore after_save and after_validation on topic&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='vi'&gt;@observer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expects&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:after_save&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;never&lt;/span&gt;
          &lt;span class='vi'&gt;@observer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expects&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:after_validation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;never&lt;/span&gt;
          &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:notify&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_save&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:notify&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_validation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
    
      &lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;call&lt;/span&gt;

    &lt;span class='k'&gt;end&lt;/span&gt;
    
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;All the greatness of blocks is often overlooked in Ruby. Since a &lt;code&gt;test&lt;/code&gt; method that takes a block was added to &lt;code&gt;ActiveSupport::TestCase&lt;/code&gt;, a lot of new possibilities open up. In this case, since the test is defined from a block, I can make an enclosing block, define my object as a local variable there, then define all my test methods to make use of it. I don&amp;#8217;t need to instantiate an object that other tests don&amp;#8217;t even use in the &lt;code&gt;setup&lt;/code&gt; method, and I can group tests in a slightly cleaner way.&lt;/p&gt;

&lt;p&gt;This isn&amp;#8217;t always an applicable technique - in cases where a new &lt;code&gt;Topic&lt;/code&gt; instance was needed every instance, this would fall over. If you need a single instance of an object for your tests, and want to organize them a little more nicely, consider it next time you&amp;#8217;re writing a test in a testing environment that lacks actual contexts. Moving your testing to use something like &lt;a href='http://www.thoughtbot.com/projects/shoulda'&gt;Shoulda&lt;/a&gt; or &lt;a href='http://rspec.info/'&gt;RSpec&lt;/a&gt; is most likely a better long-term fix.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Merb+Rails? Meals? What the fuck is Ruby on Meals?</title>
   <link href="http://annealer.org/2008/12/23/rails-and-merb-merge.html"/>
   <updated>2008-12-23T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/23/rails-and-merb-merge</id>
   <content type="html">&lt;p&gt;So according to &lt;a href='http://weblog.rubyonrails.com/2008/12/23/merb-gets-merged-into-rails-3'&gt;&amp;#8216;our boy DHH&amp;#8217;&lt;/a&gt; Merb and Rails are merging. I think this can only be a good thing. I found the Merb community to be really adversarial to people using Rails and I never understood why. Here&amp;#8217;s a list of my experiences with Merb and DataMapper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frustrating&lt;/li&gt;

&lt;li&gt;Annoying&lt;/li&gt;

&lt;li&gt;Frustrating and annoying&lt;/li&gt;

&lt;li&gt;Frustrating and annoying and totally fucking up all my gems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of this was probably DataMapper&amp;#8217;s fault, considering &lt;a href='http://datamapper.org/'&gt;their entire site&lt;/a&gt; has now been replaced by a wiki that doesn&amp;#8217;t explain how to get something resembling a stable install going but sure has a pretty logo and a Twitter feed. They really seemed to go hand in hand though. Alternative web framework, alternative ORM. As frustrating as it can sometimes be that Rails is &lt;a href='http://www.flickr.com/photos/doesrails/128015501/'&gt;so opinionated&lt;/a&gt;, it&amp;#8217;s nice to know I can &lt;code&gt;gem install rails&lt;/code&gt; and have a stable setup out of the box.&lt;/p&gt;

&lt;p&gt;Good luck to Rails&amp;#8230; Merb&amp;#8230; Rerb core on getting 3.0 out and keeping it stable.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Callbacks got refactored to ActiveSupport in Rails 2.1</title>
   <link href="http://annealer.org/2008/12/22/callbacks-in-activesupport.html"/>
   <updated>2008-12-22T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/22/callbacks-in-activesupport</id>
   <content type="html">&lt;p&gt;Chalk this up to something I never actually noticed until fairly recently. Callbacks got refactored out of ActiveRecord. I&amp;#8217;ve ended up ghetto-implementing similar functionality before, and this does everything I could want it to. Here&amp;#8217;s a trite example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;    &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Playable&lt;/span&gt;
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nc'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nf'&gt;included&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;base&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:include&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;ActiveSupport&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Callbacks&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;define_callbacks&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:before_play&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:after_play&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;play&lt;/span&gt;
        &lt;span class='n'&gt;run_callbacks&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:before_play&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;yield&lt;/span&gt;
        &lt;span class='n'&gt;run_callbacks&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:after_play&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Track&lt;/span&gt;
      &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;Playable&lt;/span&gt;

      &lt;span class='n'&gt;before_play&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;About to play&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='n'&gt;after_play&lt;/span&gt; &lt;span class='ss'&gt;:post_play_message&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;play&lt;/span&gt;
        &lt;span class='k'&gt;super&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
          &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Playing&amp;quot;&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='kp'&gt;private&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;post_play_message&lt;/span&gt;
        &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Done playing&amp;quot;&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;


    &lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;Track&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;play&lt;/span&gt;
    &lt;span class='no'&gt;About&lt;/span&gt; &lt;span class='n'&gt;to&lt;/span&gt; &lt;span class='n'&gt;play&lt;/span&gt;
    &lt;span class='no'&gt;Playing&lt;/span&gt;
    &lt;span class='no'&gt;Done&lt;/span&gt; &lt;span class='n'&gt;playing&lt;/span&gt;
    
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Waiting for Validations to finally follow suit and not be so AR-specific. There&amp;#8217;s like two or three different implementations of an Errors object in Rails now, last I checked.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Back to the blarghosphere.</title>
   <link href="http://annealer.org/2008/12/22/blarghosphere-first-post.html"/>
   <updated>2008-12-22T00:00:00-08:00</updated>
   <id>http://annealer.org/2008/12/22/blarghosphere-first-post</id>
   <content type="html">&lt;p&gt;So I&amp;#8217;m back in the blarghosphere where I can pollute the tubes with my own special brand of crap. This time I&amp;#8217;m using &lt;a href='http://github.com/mojombo/jekyll/tree/master'&gt;Jekyll&lt;/a&gt;, a static file based site/blog builder. I was writing my own and Jekyll came out in the meantime, and does almost exactly what I want, except a few things I &lt;a href='https://github.com/gabrielg/jekyll/tree'&gt;patched in my GitHub fork&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll eventually be putting comment support up here, via Grumble &lt;a href='http://rosettastoners.com/grumble_test.html'&gt;(test page here)&lt;/a&gt;, a service I&amp;#8217;ve built that is intended to be used to comment on any HTTP resource. Following REST and staying addressable turns out to be a good thing, whowouldathunkit?&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re putting up your own Jekyll based blog, &lt;a href='http://code.google.com/p/mongoose/'&gt;SHTTPD/Mongoose&lt;/a&gt; is great for testing - you can just change into your &amp;#8216;site&amp;#8217; dir and fire up SHTTPD on the right port, and have all your absolutely referenced CSS / HTML work properly.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s see how long I can maintain this before I get bored of it. The fact I don&amp;#8217;t give a shit how this looks in IE shows how far we&amp;#8217;ve come browser-wise. It&amp;#8217;s not that I &lt;em&gt;can&amp;#8217;t&lt;/em&gt; fix it, it&amp;#8217;s that for my personal site, I &lt;em&gt;won&amp;#8217;t&lt;/em&gt; fix it. I&amp;#8217;ll save that kind of torture for paid work, not make it a hobby.&lt;/p&gt;</content>
 </entry>
 
 
</feed>