<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Sporkmonger</title>
  <subtitle>purveyor of fabulously ambiguous eating utensils</subtitle>
  <id>urn:uuid:fa6d0b87-3f36-517d-b9b7-1349f8c3fc6b</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://sporkmonger.com/entries/feed" rel="self" type="application/atom+xml"/>
  <link href="http://sporkmonger.com/" rel="alternate" type="text/html"/>
  <updated>2008-03-01T16:55:45Z</updated>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:75db4764-38ed-4ee1-9109-70d163fe9e95</id>
    <published>2008-03-01T16:27:00Z</published>
    <updated>2008-03-01T16:55:45Z</updated>
    <category term="rake"/>
    <category term="sake"/>
    <link href="http://sporkmonger.com/2008/3/1/sake-is-pretty-awesome" rel="alternate" type="text/html"/>
    <title>Sake Is Pretty Awesome</title>
<content type="html">
            &lt;p&gt;So, I happened upon &lt;a href=&quot;http://brian.maybeyoureinsane.net/blog/2008/01/31/git-sake-tasks/&quot;&gt;this entry&lt;/a&gt; earlier today.  I hadn&#8217;t previously seen &lt;a href=&quot;http://errtheblog.com/posts/60-sake-bomb&quot;&gt;sake&lt;/a&gt; and I&#8217;ve got to say, it&#8217;s really quite handy.  Having a global set of rake tasks is just super-useful.  Thanks Chris!  (And thanks Brian because I wouldn&#8217;t have noticed it otherwise!)&lt;/p&gt;


Trust me, you want to:
&lt;pre&gt;&lt;code&gt;
sudo gem install sake
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:993aabd5-1f21-4623-a0b8-0af2f5e4744d</id>
    <published>2008-02-01T02:54:00Z</published>
    <updated>2008-02-01T03:16:48Z</updated>
    <category term="addressable"/>
    <category term="feedtools"/>
    <category term="ruby"/>
    <link href="http://sporkmonger.com/2008/2/1/feedtools-0-2-27" rel="alternate" type="text/html"/>
    <title>FeedTools 0.2.27</title>
<content type="html">
            &lt;p&gt;It&#8217;s been a long time coming I guess.  Haven&#8217;t really had much time to work on it, and when I have, I &lt;em&gt;really&lt;/em&gt; haven&#8217;t wanted to.  Of all the software I&#8217;ve ever written, I consider &lt;a href=&quot;http://rubyforge.org/projects/feedtools/&quot;&gt;FeedTools&lt;/a&gt; to be the most embarrassingly bad.  Ironically, it&#8217;s probably also the most popular piece of software I&#8217;ve ever written.&lt;/p&gt;


	&lt;p&gt;Anyways, it&#8217;s been so long since I made some of the changes that I have listed in the &lt;span class=&quot;caps&quot;&gt;CHANGELOG&lt;/span&gt; that I don&#8217;t even remember making them.  They probably really did happen.  Everything finally green-bars in any case.  I ditched HTree and replaced it with &lt;a href=&quot;http://code.google.com/p/html5lib/&quot;&gt;html5lib&lt;/a&gt;.  I was surprised by how easy the transition was, but it&#8217;s definitely slower for it.  I fixed the issues with resolving relative URIs.  Got rid of some ugly hacks, added a few more.  The schema for the cache changed slightly.  On balance, it&#8217;s better than 0.2.26, but in keeping with tradition, it&#8217;s also a little slower.  If you need speed, you&#8217;ve come to the wrong place.  That hasn&#8217;t changed at all.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve learned a lot in the time (What has it been now? 3 years?) since I originally set out to write this parser.  Certainly the most important lesson I learned was, &#8220;If you build on a lousy foundation, the entire thing&#8217;s going to be unstable.  At best.&#8221;  I&#8217;m not sure why I didn&#8217;t realize much earlier on that &lt;span class=&quot;caps&quot;&gt;REXML&lt;/span&gt; was a mistake.  Once I was far enough in that I couldn&#8217;t easily turn back, I started trying very hard not to make the original mistake in other areas.  Incidentally, that&#8217;s how &lt;a href=&quot;http://addressable.rubyforge.org/&quot;&gt;Addressable&lt;/a&gt; came into existence.  It became clear to me that Ruby&#8217;s built-in &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; parser was terrible, so I stopped using it and wrote a replacement.  A replacement that I now swear by.  If FeedTools is my greatest embarrassment, Addressable is (for the moment) my pride and joy.  (Actually, that might be a bit much.  It&#8217;s still just a &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; parser.)&lt;/p&gt;


	&lt;p&gt;Also, while I was at it, I put the &lt;a href=&quot;http://feedtools.rubyforge.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; up again.&lt;/p&gt;


	&lt;p&gt;Hopefully I won&#8217;t have to touch FeedTools again for a very long time.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:cbc119e8-13fc-46d0-8087-4a24741a646c</id>
    <published>2008-01-16T10:07:00Z</published>
    <updated>2008-01-16T10:23:12Z</updated>
    <category term="os x"/>
    <category term="security"/>
    <link href="http://sporkmonger.com/2008/1/16/tip-require-password-to-restart-os-x" rel="alternate" type="text/html"/>
    <title>Tip: Require password to restart OS X</title>
<content type="html">
            &lt;p&gt;So, last week I was running this ridiculous database migration for importing WordNet into MySQL via ActiveRecord.  (I would like to file a complaint by the way.  If a migration takes 8 days to finish, you need to use something other than ActiveRecord to get stuff into the database.  Seriously.)&lt;/p&gt;


	&lt;p&gt;A family member decided they would like to watch a TV show on my laptop.  Fairly normal.  Unfortunately, my PowerBook decided to act up and wouldn&#8217;t play any sound.  Still not sure what the deal is with that, it&#8217;s happening off and on.  Only thing that fixes it is a reboot.  Well, the family member in question took it upon themselves to reboot while my migration was in progress and about 98% done.  For those of you reading this in horror, don&#8217;t worry, I hacked on the migration code for about 20 minutes and got it to resume where it left off.&lt;/p&gt;


	&lt;p&gt;That said, I decided I didn&#8217;t want that ever happening again.  The obvious solution was to check off the little checkbox in System Preferences -&amp;gt; Security for &#8220;Require password to shutdown or reboot&#8221;.  Except that it doesn&#8217;t exist.  Apple?  Are you listening?  I&#8217;d like to be able to remind users of my computer that they really need to ask me before rebooting my computer.  Anyways.  Here&#8217;s how to do it without the handy checkbox:&lt;/p&gt;


	&lt;p&gt;Create a new user on your machine.  Regular old user, no admin access.  Name it &#8220;Lockdown&#8221;.  Give it a lightning bolt icon or something.  Enable fast user switching.  Log in to your account as normal, then once you&#8217;re logged in, switch to the Lockdown account.  Sign it in, leave it running, then switch back.  Now &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt; will require a password before rebooting.&lt;/p&gt;


	&lt;p&gt;It&#8217;s a hack, and there&#8217;s no really good reason to leave it running all the time, but it&#8217;s a good idea if you&#8217;ve got an important process going that you really don&#8217;t want getting killed off accidentally by well-meaning family members.  And yes, they could still hit the power button or pull the battery on the laptop, but that&#8217;s a lot harder to do accidentally.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:3b53468c-31c9-4c98-bb89-a19e82dd7b65</id>
    <published>2007-12-24T23:25:00Z</published>
    <updated>2007-12-24T23:27:13Z</updated>
    <category term="os x"/>
    <category term="property list"/>
    <category term="sass"/>
    <category term="textmate"/>
    <link href="http://sporkmonger.com/2007/12/24/sass-textmate-bundle" rel="alternate" type="text/html"/>
    <title>Sass TextMate Bundle</title>
<summary type="html">&lt;p&gt;I went a googling, looking for a &lt;a href=&quot;http://haml.hamptoncatlin.com/docs/sass&quot;&gt;Sass&lt;/a&gt; TextMate bundle.  There didn&#8217;t seem to be one, so I sat down and threw one together.  Hopefully, this should make writing Syntactically Awesome StyleSheets a little easier for TextMate users.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I went a googling, looking for a &lt;a href=&quot;http://haml.hamptoncatlin.com/docs/sass&quot;&gt;Sass&lt;/a&gt; TextMate bundle.  There didn&#8217;t seem to be one, so I sat down and threw one together.  Hopefully, this should make writing Syntactically Awesome StyleSheets a little easier for TextMate users.&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;75&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;76&lt;tt&gt;
&lt;/tt&gt;77&lt;tt&gt;
&lt;/tt&gt;78&lt;tt&gt;
&lt;/tt&gt;79&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;81&lt;tt&gt;
&lt;/tt&gt;82&lt;tt&gt;
&lt;/tt&gt;83&lt;tt&gt;
&lt;/tt&gt;84&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;85&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;86&lt;tt&gt;
&lt;/tt&gt;87&lt;tt&gt;
&lt;/tt&gt;88&lt;tt&gt;
&lt;/tt&gt;89&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;90&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;91&lt;tt&gt;
&lt;/tt&gt;92&lt;tt&gt;
&lt;/tt&gt;93&lt;tt&gt;
&lt;/tt&gt;94&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;95&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;96&lt;tt&gt;
&lt;/tt&gt;97&lt;tt&gt;
&lt;/tt&gt;98&lt;tt&gt;
&lt;/tt&gt;99&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;101&lt;tt&gt;
&lt;/tt&gt;102&lt;tt&gt;
&lt;/tt&gt;103&lt;tt&gt;
&lt;/tt&gt;104&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;105&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;106&lt;tt&gt;
&lt;/tt&gt;107&lt;tt&gt;
&lt;/tt&gt;108&lt;tt&gt;
&lt;/tt&gt;109&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;110&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;111&lt;tt&gt;
&lt;/tt&gt;112&lt;tt&gt;
&lt;/tt&gt;113&lt;tt&gt;
&lt;/tt&gt;114&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;115&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;116&lt;tt&gt;
&lt;/tt&gt;117&lt;tt&gt;
&lt;/tt&gt;118&lt;tt&gt;
&lt;/tt&gt;119&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;120&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;121&lt;tt&gt;
&lt;/tt&gt;122&lt;tt&gt;
&lt;/tt&gt;123&lt;tt&gt;
&lt;/tt&gt;124&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;125&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;126&lt;tt&gt;
&lt;/tt&gt;127&lt;tt&gt;
&lt;/tt&gt;128&lt;tt&gt;
&lt;/tt&gt;129&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;130&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;131&lt;tt&gt;
&lt;/tt&gt;132&lt;tt&gt;
&lt;/tt&gt;133&lt;tt&gt;
&lt;/tt&gt;134&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;135&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;136&lt;tt&gt;
&lt;/tt&gt;137&lt;tt&gt;
&lt;/tt&gt;138&lt;tt&gt;
&lt;/tt&gt;139&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;140&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;141&lt;tt&gt;
&lt;/tt&gt;142&lt;tt&gt;
&lt;/tt&gt;143&lt;tt&gt;
&lt;/tt&gt;144&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;145&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;146&lt;tt&gt;
&lt;/tt&gt;147&lt;tt&gt;
&lt;/tt&gt;148&lt;tt&gt;
&lt;/tt&gt;149&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;150&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;151&lt;tt&gt;
&lt;/tt&gt;152&lt;tt&gt;
&lt;/tt&gt;153&lt;tt&gt;
&lt;/tt&gt;154&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;155&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;156&lt;tt&gt;
&lt;/tt&gt;157&lt;tt&gt;
&lt;/tt&gt;158&lt;tt&gt;
&lt;/tt&gt;159&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;160&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;161&lt;tt&gt;
&lt;/tt&gt;162&lt;tt&gt;
&lt;/tt&gt;163&lt;tt&gt;
&lt;/tt&gt;164&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;165&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;166&lt;tt&gt;
&lt;/tt&gt;167&lt;tt&gt;
&lt;/tt&gt;168&lt;tt&gt;
&lt;/tt&gt;169&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;170&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;171&lt;tt&gt;
&lt;/tt&gt;172&lt;tt&gt;
&lt;/tt&gt;173&lt;tt&gt;
&lt;/tt&gt;174&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;175&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;176&lt;tt&gt;
&lt;/tt&gt;177&lt;tt&gt;
&lt;/tt&gt;178&lt;tt&gt;
&lt;/tt&gt;179&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;180&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;181&lt;tt&gt;
&lt;/tt&gt;182&lt;tt&gt;
&lt;/tt&gt;183&lt;tt&gt;
&lt;/tt&gt;184&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;185&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;186&lt;tt&gt;
&lt;/tt&gt;187&lt;tt&gt;
&lt;/tt&gt;188&lt;tt&gt;
&lt;/tt&gt;189&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;190&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;191&lt;tt&gt;
&lt;/tt&gt;192&lt;tt&gt;
&lt;/tt&gt;193&lt;tt&gt;
&lt;/tt&gt;194&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;195&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;196&lt;tt&gt;
&lt;/tt&gt;197&lt;tt&gt;
&lt;/tt&gt;198&lt;tt&gt;
&lt;/tt&gt;199&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;200&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;201&lt;tt&gt;
&lt;/tt&gt;202&lt;tt&gt;
&lt;/tt&gt;203&lt;tt&gt;
&lt;/tt&gt;204&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;205&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;206&lt;tt&gt;
&lt;/tt&gt;207&lt;tt&gt;
&lt;/tt&gt;208&lt;tt&gt;
&lt;/tt&gt;209&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;210&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;211&lt;tt&gt;
&lt;/tt&gt;212&lt;tt&gt;
&lt;/tt&gt;213&lt;tt&gt;
&lt;/tt&gt;214&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;215&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;{&lt;tt&gt;
&lt;/tt&gt;  scopeName = 'source.sass';&lt;tt&gt;
&lt;/tt&gt;  comment = '';&lt;tt&gt;
&lt;/tt&gt;  fileTypes = ( 'sass' );&lt;tt&gt;
&lt;/tt&gt;  patterns = (&lt;tt&gt;
&lt;/tt&gt;    {  name = 'meta.variable-declaration.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '^(\!)([a-zA-Z0-9_-]+)\s*(=)';&lt;tt&gt;
&lt;/tt&gt;      end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = {&lt;tt&gt;
&lt;/tt&gt;        1 = { name = 'punctuation.definition.entity.css'; };&lt;tt&gt;
&lt;/tt&gt;        2 = { name = 'variable.other.sass'; };&lt;tt&gt;
&lt;/tt&gt;        3 = { name = 'punctuation.definition.entity.css'; };&lt;tt&gt;
&lt;/tt&gt;      };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = ( { include = '#property-value'; } );&lt;tt&gt;
&lt;/tt&gt;    },&lt;tt&gt;
&lt;/tt&gt;    {  name = 'meta.selector.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '^(?=[:.*#a-zA-Z])';&lt;tt&gt;
&lt;/tt&gt;      end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  include = '#comment-block'; },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.name.tag.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\b(a|abbr|acronym|address|area|b|base|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|dt|em|fieldset|form|frame|frameset|(h[1-6])|head|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|meta|noframes|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var)\b';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.other.attribute-name.class.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(\.)[a-zA-Z0-9_-]+';&lt;tt&gt;
&lt;/tt&gt;          captures = { 1 = { name = 'punctuation.definition.entity.css'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.other.attribute-name.id.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(#)[a-zA-Z][a-zA-Z0-9_-]*';&lt;tt&gt;
&lt;/tt&gt;          captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.name.tag.wildcard.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\*';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.other.attribute-name.pseudo-element.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(:+)\b(after|before|first-child|first-letter|first-line|selection)\b';&lt;tt&gt;
&lt;/tt&gt;          captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'entity.other.attribute-name.pseudo-class.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(:)\b(active|hover|link|visited|focus)\b';&lt;tt&gt;
&lt;/tt&gt;          captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'meta.attribute-selector.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(?i)(\[)\s*(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)(?:\s*([~|^$*]?=)\s*(?:(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)|((?&amp;gt;([''&amp;quot;])(?:[^\\]|\\.)*?(\6)))))?\s*(\])';&lt;tt&gt;
&lt;/tt&gt;          captures = {&lt;tt&gt;
&lt;/tt&gt;            1 = { name = 'punctuation.definition.entity.sass'; };&lt;tt&gt;
&lt;/tt&gt;            2 = { name = 'entity.other.attribute-name.attribute.sass'; };&lt;tt&gt;
&lt;/tt&gt;            3 = { name = 'punctuation.separator.operator.sass'; };&lt;tt&gt;
&lt;/tt&gt;            4 = { name = 'string.unquoted.attribute-value.sass'; };&lt;tt&gt;
&lt;/tt&gt;            5 = { name = 'string.quoted.double.attribute-value.sass'; };&lt;tt&gt;
&lt;/tt&gt;            6 = { name = 'punctuation.definition.string.begin.sass'; };&lt;tt&gt;
&lt;/tt&gt;            7 = { name = 'punctuation.definition.string.end.sass'; };&lt;tt&gt;
&lt;/tt&gt;          };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    },&lt;tt&gt;
&lt;/tt&gt;    {  include = '#comment-block'; },&lt;tt&gt;
&lt;/tt&gt;    {  name = 'meta.at-rule.import.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '^\s*((@)import\b)';&lt;tt&gt;
&lt;/tt&gt;      end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = {&lt;tt&gt;
&lt;/tt&gt;        1 = { name = 'keyword.control.at-rule.import.sass'; };&lt;tt&gt;
&lt;/tt&gt;        2 = { name = 'punctuation.definition.keyword.sass'; };&lt;tt&gt;
&lt;/tt&gt;      };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  include = '#string-double'; },&lt;tt&gt;
&lt;/tt&gt;        {  begin = '(url)\s*(\()\s*';&lt;tt&gt;
&lt;/tt&gt;          end = '\s*(\))\s*';&lt;tt&gt;
&lt;/tt&gt;          beginCaptures = {&lt;tt&gt;
&lt;/tt&gt;            1 = { name = 'support.function.url.sass'; };&lt;tt&gt;
&lt;/tt&gt;            2 = { name = 'punctuation.section.function.sass'; };&lt;tt&gt;
&lt;/tt&gt;          };&lt;tt&gt;
&lt;/tt&gt;          endCaptures = { 1 = { name = 'punctuation.section.function.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;          patterns = (&lt;tt&gt;
&lt;/tt&gt;            {  name = 'variable.parameter.url.sass';&lt;tt&gt;
&lt;/tt&gt;              match = '[^''&amp;quot;) \t]+';&lt;tt&gt;
&lt;/tt&gt;            },&lt;tt&gt;
&lt;/tt&gt;            {  include = '#string-single'; },&lt;tt&gt;
&lt;/tt&gt;            {  include = '#string-double'; },&lt;tt&gt;
&lt;/tt&gt;          );&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'variable.parameter.url.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '([^&amp;quot;''\n;]+)';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    },&lt;tt&gt;
&lt;/tt&gt;    {  name = 'meta.at-rule.media.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '^\s*((@)media)\s+(((all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)\s*,?\s*)+)\s*{';&lt;tt&gt;
&lt;/tt&gt;      end = '\s*((?=;|\}))';&lt;tt&gt;
&lt;/tt&gt;      captures = {&lt;tt&gt;
&lt;/tt&gt;        1 = { name = 'keyword.control.at-rule.media.sass'; };&lt;tt&gt;
&lt;/tt&gt;        2 = { name = 'punctuation.definition.keyword.sass'; };&lt;tt&gt;
&lt;/tt&gt;        3 = { name = 'support.constant.media.sass'; };&lt;tt&gt;
&lt;/tt&gt;      };&lt;tt&gt;
&lt;/tt&gt;      patterns = ( { include = '$self'; } );&lt;tt&gt;
&lt;/tt&gt;    },&lt;tt&gt;
&lt;/tt&gt;    {  name = 'meta.property-name.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '(?&amp;lt;![-a-z])(:)(?=[-a-z])';&lt;tt&gt;
&lt;/tt&gt;      end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = { 1 = { name = 'punctuation.definition.entity.css'; }; };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  name = 'support.type.property-name.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\b(azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|family|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|-moz-border-radius|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow(-[xy])?|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|style|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|weight|white-space|widows|width|word-spacing|z-index)\b';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  include = '#property-value'; },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    },&lt;tt&gt;
&lt;/tt&gt;  );&lt;tt&gt;
&lt;/tt&gt;  repository = {&lt;tt&gt;
&lt;/tt&gt;    comment-block = {&lt;tt&gt;
&lt;/tt&gt;      name = 'comment.block.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '(/\*|//)';&lt;tt&gt;
&lt;/tt&gt;      end = '$';&lt;tt&gt;
&lt;/tt&gt;      captures = { 0 = { name = 'punctuation.definition.comment.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;    };&lt;tt&gt;
&lt;/tt&gt;    property-value = {&lt;tt&gt;
&lt;/tt&gt;      name = 'meta.property-value.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '(:)?\s+';&lt;tt&gt;
&lt;/tt&gt;      end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  name = 'meta.variable-assignment.sass';&lt;tt&gt;
&lt;/tt&gt;          begin = '(=)\s*(\!)([a-zA-Z0-9_-]+)';&lt;tt&gt;
&lt;/tt&gt;          end = '(;)?$';&lt;tt&gt;
&lt;/tt&gt;          beginCaptures = {&lt;tt&gt;
&lt;/tt&gt;            1 = { name = 'punctuation.definition.entity.css'; };&lt;tt&gt;
&lt;/tt&gt;            2 = { name = 'punctuation.definition.entity.css'; };&lt;tt&gt;
&lt;/tt&gt;            3 = { name = 'variable.other.sass'; };&lt;tt&gt;
&lt;/tt&gt;          };&lt;tt&gt;
&lt;/tt&gt;          endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'support.constant.property-value.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\b(absolute|all-scroll|always|auto|baseline|below|bidi-override|block|bold|bolder|both|bottom|break-all|break-word|capitalize|center|char|circle|col-resize|collapse|crosshair|dashed|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|groove|hand|help|hidden|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace)\b';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'support.constant.font-name.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(\b(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace)\b)';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'support.constant.color.w3c-standard-color-name.sass';&lt;tt&gt;
&lt;/tt&gt;          comment = 'http://www.w3schools.com/css/css_colors.asp';&lt;tt&gt;
&lt;/tt&gt;          match = '\b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)\b';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'invalid.deprecated.color.w3c-non-standard-color-name.sass';&lt;tt&gt;
&lt;/tt&gt;          comment = 'These colours are mostly recognised but will not validate. ref: http://www.w3schools.com/css/css_colornames.asp';&lt;tt&gt;
&lt;/tt&gt;          match = '\b(seagreen|hotpink|lawngreen|darkgreen|violet|darkred|crimson|green|sandybrown|navy|magenta|darkslategray|steelblue|silver|darkgrey|mistyrose|gray|aliceblue|blueviolet|lightpink|saddlebrown|chocolate|limegreen|lightslategray|yellowgreen|pink|lightskyblue|indigo|lightblue|floralwhite|navajowhite|mediumvioletred|honeydew|aquamarine|blue|olivedrab|palegreen|slategray|lavenderblush|wheat|moccasin|mediumturquoise|mediumspringgreen|lightcoral|mintcream|tomato|lightgrey|black|darkmagenta|dimgray|darkturquoise|midnightblue|plum|indianred|coral|lightcyan|mediumslateblue|darkcyan|darkslateblue|darkkhaki|ivory|azure|khaki|powderblue|darkgoldenrod|orangered|burlywood|turquoise|royalblue|maroon|cornsilk|antiquewhite|yellow|teal|orange|grey|darkslategrey|slateblue|seashell|darkorchid|snow|lightslategrey|cyan|greenyellow|palevioletred|goldenrod|deepskyblue|lightyellow|lightseagreen|sienna|lemonchiffon|darkviolet|paleturquoise|slategrey|skyblue|purple|mediumpurple|cadetblue|fuchsia|chartreuse|darksalmon|lightgoldenrodyellow|white|springgreen|olive|forestgreen|peachpuff|peru|dimgrey|mediumseagreen|thistle|firebrick|darkgray|mediumaquamarine|darkolivegreen|mediumblue|palegoldenrod|blanchedalmond|ghostwhite|gold|gainsboro|darkseagreen|cornflowerblue|lime|lavender|beige|orchid|mediumorchid|whitesmoke|bisque|lightgray|tan|salmon|rosybrown|red|dodgerblue|brown|aqua|oldlace|deeppink|papayawhip|lightsalmon|lightsteelblue|darkorange|darkblue|linen|lightgreen)\b';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'constant.numeric.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(-|\+)?\s*[0-9]+(\.[0-9]+)?';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'keyword.other.unit.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(?&amp;lt;=[\d])(px|pt|cm|mm|in|em|ex|pc)\b|%';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'constant.other.color.rgb-value.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b';&lt;tt&gt;
&lt;/tt&gt;          captures = { 1 = { name = 'punctuation.definition.constant.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  include = '#string-double'; },&lt;tt&gt;
&lt;/tt&gt;        {  include = '#string-single'; },&lt;tt&gt;
&lt;/tt&gt;        {  begin = '(rgb|url|attr|counter|counters)\s*(\()';&lt;tt&gt;
&lt;/tt&gt;          end = '(\))';&lt;tt&gt;
&lt;/tt&gt;          beginCaptures = {&lt;tt&gt;
&lt;/tt&gt;            1 = { name = 'support.function.misc.sass'; };&lt;tt&gt;
&lt;/tt&gt;            2 = { name = 'punctuation.section.function.sass'; };&lt;tt&gt;
&lt;/tt&gt;          };&lt;tt&gt;
&lt;/tt&gt;          endCaptures = { 1 = { name = 'punctuation.section.function.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;          patterns = (&lt;tt&gt;
&lt;/tt&gt;            {  include = '#string-single'; },&lt;tt&gt;
&lt;/tt&gt;            {  include = '#string-double'; },&lt;tt&gt;
&lt;/tt&gt;            {  name = 'constant.other.color.rgb-value.sass';&lt;tt&gt;
&lt;/tt&gt;              match = '(\b0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\b)';&lt;tt&gt;
&lt;/tt&gt;            },&lt;tt&gt;
&lt;/tt&gt;            {  name = 'constant.other.color.rgb-percentage.sass';&lt;tt&gt;
&lt;/tt&gt;              match = '\b([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%';&lt;tt&gt;
&lt;/tt&gt;            },&lt;tt&gt;
&lt;/tt&gt;            {  name = 'variable.parameter.misc.sass';&lt;tt&gt;
&lt;/tt&gt;              match = '[^''&amp;quot;) \t]+';&lt;tt&gt;
&lt;/tt&gt;            },&lt;tt&gt;
&lt;/tt&gt;          );&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;        {  name = 'keyword.other.important.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\!\s*important';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    };&lt;tt&gt;
&lt;/tt&gt;    string-double = {&lt;tt&gt;
&lt;/tt&gt;      name = 'string.quoted.double.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = '&amp;quot;';&lt;tt&gt;
&lt;/tt&gt;      end = '&amp;quot;';&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = { 0 = { name = 'punctuation.definition.string.begin.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 0 = { name = 'punctuation.definition.string.end.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  name = 'constant.character.escape.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\\.';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    };&lt;tt&gt;
&lt;/tt&gt;    string-single = {&lt;tt&gt;
&lt;/tt&gt;      name = 'string.quoted.single.sass';&lt;tt&gt;
&lt;/tt&gt;      begin = &amp;quot;'&amp;quot;;&lt;tt&gt;
&lt;/tt&gt;      end = &amp;quot;'&amp;quot;;&lt;tt&gt;
&lt;/tt&gt;      beginCaptures = { 0 = { name = 'punctuation.definition.string.begin.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      endCaptures = { 0 = { name = 'punctuation.definition.string.end.sass'; }; };&lt;tt&gt;
&lt;/tt&gt;      patterns = (&lt;tt&gt;
&lt;/tt&gt;        {  name = 'constant.character.escape.sass';&lt;tt&gt;
&lt;/tt&gt;          match = '\\.';&lt;tt&gt;
&lt;/tt&gt;        },&lt;tt&gt;
&lt;/tt&gt;      );&lt;tt&gt;
&lt;/tt&gt;    };&lt;tt&gt;
&lt;/tt&gt;  };&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This code was based on the existing &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; bundle, and may still have bugs.  This is my first serious attempt at writing a bundle, so it probably needs work in spots.  Let me know if you find any issues.  I&#8217;ll update this entry with any changes made.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:f32a011f-6ba0-42f1-ad04-101b84bfa8da</id>
    <published>2007-11-04T02:29:00Z</published>
    <updated>2007-11-04T02:48:01Z</updated>
    <category term="addressable"/>
    <category term="uri"/>
    <link href="http://sporkmonger.com/2007/11/4/addressable-now-one-point-oh" rel="alternate" type="text/html"/>
    <title>Addressable Now One Point Oh</title>
<content type="html">
            &lt;p&gt;I just released version 1.0.0 of my &lt;a href=&quot;http://addressable.rubyforge.org/&quot;&gt;Addressable library&lt;/a&gt;.  The most useful change is the addition of a new heuristic parsing method, similar to how most browsers handle URIs entered through their address bars.  Passing &#8220;example.com&#8221; to the &lt;code&gt;heuristic_parse&lt;/code&gt; method will end up returning a &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; that is equivalent to &#8220;http://example.com&#8221;.  The &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; can then be further normalized as necessary.&lt;/p&gt;


	&lt;p&gt;In addition, there are several minor changes that might cause compatibility issues (although probably not).  The path component of a &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; is now guaranteed to never equal nil.  The code in the &lt;code&gt;parse&lt;/code&gt; method for handling the feed pseudo-protocol has been removed and placed within the &lt;code&gt;heuristic_parse&lt;/code&gt; method where it belonged in the first place.  The &lt;code&gt;to_h&lt;/code&gt; method has been renamed to &lt;code&gt;to_hash&lt;/code&gt; so that coercion will work.  There were also a couple of small bug fixes, mostly related to routing.&lt;/p&gt;


	&lt;p&gt;All of that stuff is great of course, but the main reason I&#8217;m slapping the &#8220;One Point Oh&#8221; sticker on this thing and calling it &#8220;done&#8221; is that now, in addition to having 100% code coverage, Addressable can now manage to go through the heckling process with no surviving code mutations.  That&#8217;s a pretty high bar to get over, so I think it&#8217;s fair to call this thing finished.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:21cdb3ba-bccf-4c7e-a4f4-40d9ab3d2256</id>
    <published>2007-09-19T07:08:00Z</published>
    <updated>2007-09-19T07:11:37Z</updated>
    <category term="ideas"/>
    <category term="insomnia"/>
    <link href="http://sporkmonger.com/2007/9/19/insomnia-the-good-the-bad-and-the-ugly" rel="alternate" type="text/html"/>
    <title>Insomnia: The Good, the Bad, and the Ugly</title>
<content type="html">
            &lt;ul&gt;
	&lt;li&gt;The Good: Plenty of time to hatch brilliant ideas.&lt;/li&gt;
		&lt;li&gt;The Bad: Brilliant ideas do not help you fall asleep.&lt;/li&gt;
		&lt;li&gt;The Ugly: In the morning, you&#8217;re too tired to implement anything.&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:e9c57c6e-0879-49f5-aef2-735750ca1701</id>
    <published>2007-09-05T04:51:00Z</published>
    <updated>2007-09-05T20:45:45Z</updated>
    <category term="addressable"/>
    <category term="rspec"/>
    <category term="ruby"/>
    <link href="http://sporkmonger.com/2007/9/5/introducing-addressable" rel="alternate" type="text/html"/>
    <title>Introducing Addressable</title>
<content type="html">
            &lt;p&gt;So, after 3 months, I&#8217;m back from my excursion to Africa.  Don&#8217;t worry, I&#8217;m not coming back empty-handed.&lt;/p&gt;


	&lt;p&gt;I thought my fellow rubyists might benefit from the &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; implementation I&#8217;ve been using in various projects, so I&#8217;ve extracted it out into its own library. In the process, I improved a few things here and there, added support for &lt;a href=&quot;http://bitworking.org/projects/URI-Templates/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; Templates&lt;/a&gt;, and fleshed out the specifications a bit more.&lt;/p&gt;


	&lt;p&gt;I introduce to you the &lt;a href=&quot;http://addressable.rubyforge.org/&quot;&gt;Addressable&lt;/a&gt; library.&lt;/p&gt;


	&lt;p&gt;It has about a 2:1 spec to code ratio, 100.0% code coverage, and it has gone through plenty of code &lt;a href=&quot;http://seattlerb.rubyforge.org/heckle/&quot;&gt;heckling&lt;/a&gt;.  It ought to be pretty reliable.&lt;/p&gt;


	&lt;p&gt;Hope you like it.  Let me know how it works.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I&#8217;ve added &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; Template variable extraction and I updated the documentation.  The &lt;code&gt;extract_mapping&lt;/code&gt; method should be useful for template-based routing systems for frameworks.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:f6b78890-01a0-444a-bffb-e7b26f39a2a1</id>
    <published>2007-07-06T07:27:00Z</published>
    <updated>2007-07-27T11:16:35Z</updated>
    <category term="africa"/>
    <category term="kap"/>
    <category term="maasai"/>
    <category term="photography"/>
    <category term="tanzania"/>
    <link href="http://sporkmonger.com/2007/7/6/now-available-in-tanzania" rel="alternate" type="text/html"/>
    <title>Now Available In Tanzania</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/sporkmonger/725267638/&quot;&gt;&lt;img title=&quot;Maasailand&quot; src=&quot;http://farm2.static.flickr.com/1241/725267638_895bf1a82c.jpg&quot; alt=&quot;Maasailand&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;For those of you who are interested, I&#8217;ve been in Tanzania at the &lt;a href=&quot;http://cradleoflove.com/&quot;&gt;Cradle of Love baby home&lt;/a&gt; near Arusha for the past two weeks and change.  It&#8217;s been interesting for sure, lots of holding and feeding babies, playing with toddlers, trying to get through the day with as little snot and spit on me as possible.  There&#8217;s a few spitters who make this difficult, but they make up for it by being excessively adorable.  I try not to play favorites, but Neema ends up riding my shoulders quite a bit.  I haven&#8217;t taken &lt;a href=&quot;http://www.flickr.com/photos/sporkmonger/tags/cradleoflove/&quot;&gt;a lot of pictures around the baby home&lt;/a&gt; itself, but on the various excursions we&#8217;ve taken outside, &lt;a href=&quot;http://www.flickr.com/photos/sporkmonger/&quot;&gt;the camera has come out with a fair degree of regularity&lt;/a&gt;.  There&#8217;s also some new &lt;a href=&quot;http://www.flickr.com/photos/sporkmonger/sets/72157600338727736/&quot;&gt;kite aerial photography&lt;/a&gt; shots from the trip to the bush to visit the Maasai.  If you have a Pro Flickr account, the high-resolution &lt;a href=&quot;http://www.flickr.com/photos/sporkmonger/724333567/in/set-72157600338727736/&quot;&gt;panorama shot from the kite&lt;/a&gt; is pretty neat.  I suspect that through August at least, &lt;a href=&quot;http://api.flickr.com/services/feeds/photos_public.gne?id=82552627@N00&amp;amp;#38;lang=en-us&amp;amp;#38;format=atom_10&quot;&gt;my Flickr photo stream&lt;/a&gt; will be much more interesting to subscribe to than my blog&#8217;s feed will be.  Consider adjusting accordingly.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:d2f14c6b-50a7-44d6-ab1e-35f841c56620</id>
    <published>2007-05-17T17:05:00Z</published>
    <updated>2007-05-23T12:15:12Z</updated>
    <category term="africa"/>
    <category term="kenya"/>
    <link href="http://sporkmonger.com/2007/5/17/only-in-kenya" rel="alternate" type="text/html"/>
    <title>Only In Kenya</title>
<content type="html">
            &lt;p&gt;As a few of you are probably aware by now, I will be taking a break from Ruby, and computing in general for a couple of months.  I am getting on a plane headed for Nairobi on May 20th.  I won&#8217;t be back until August 26th.  I&#8217;m not taking a computer with me, though I will have limited access through internet cafes, so email should work, but don&#8217;t expect quick replies.&lt;/p&gt;


	&lt;p&gt;For those who are curious, the intent of the trip is humanitarian in nature.  There will be trips to Uganda and Tanzania, and some volcano climbing.  I&#8217;ll be sure to take lots of photos, which will no doubt end up on Flickr.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;In London.  About to fall asleep.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;In Kenya.  Amazingly still awake.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:1c6111f4-e38b-45d1-91c2-60f27b79abd2</id>
    <published>2007-05-05T21:53:00Z</published>
    <updated>2007-05-13T05:01:01Z</updated>
    <category term="spam"/>
    <link href="http://sporkmonger.com/2007/5/5/bad-spammers-go-away" rel="alternate" type="text/html"/>
    <title>Bad Spammers! Go Away!</title>
<content type="html">
            &lt;p&gt;I finally got annoyed enough by all the comment spam.  (Probably upwards of 100 comment spams a day.)  To absolutely no one&#8217;s surprise, my IP blacklist wasn&#8217;t helping much.  I&#8217;ve now customized the comment submission system in Mephisto to include a &lt;span class=&quot;caps&quot;&gt;CAPTCHA&lt;/span&gt; of sorts.  Well, really more like a test for an actual Javascript-capable browser.  Sadly, the technique requires Javascript to be on, and I was a little too lazy to accommodate people who have it off.  If you have Javascript off, and you really, truly can&#8217;t turn it on, well, I suppose you can always email me?  The rest of site works perfectly fine with Javascript off, and I apologize in advance for letting you become a casualty of the War on Spam.  If anyone has trouble commenting, email me, I haven&#8217;t tested this thing very well&#8212;it was a five minute change.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I rather like how well this has worked out thus far.  Went from 100+ spam comments per day to zero since the code was deployed, with effectively zero chance of false positives.  I can live with that.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:71bb1f93-689b-4aa9-a132-6fdd9162ee86</id>
    <published>2007-04-02T04:07:00Z</published>
    <updated>2007-04-03T18:57:52Z</updated>
    <category term="c"/>
    <category term="mephisto"/>
    <category term="ruby"/>
    <category term="squish"/>
    <category term="uuidtools"/>
    <link href="http://sporkmonger.com/2007/4/2/relaunched-realigned" rel="alternate" type="text/html"/>
    <title>Relaunched, Realigned</title>
<content type="html">
            &lt;p&gt;If you can see this, apparently everything is working.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Ok, so there were some bugs.  Incorrect permissions and such, not-quite-right Apache settings.  But it&#8217;s likely to be more functional now.&lt;/p&gt;


	&lt;p&gt;After several weeks of work on the site, I&#8217;ve finally gotten everything moved off Typo, redesigned, and generally just looking a thousand times better than before.  I also hosed out all of the accumulated spam.  It wasn&#8217;t easy.&lt;/p&gt;


	&lt;p&gt;At Aristotle&#8217;s request, I made sure to modify the Typo conversion script (as well as Mephisto itself) to allow the feed entry GUIDs to remain the same.  I wasn&#8217;t particularly pleased to discover that Mephisto doesn&#8217;t actually store its entry GUIDs in the database&#8212;it generates them each time the feed is requested, which in my humble opinion is a terrible idea, since the information it uses to generate the IDs might change.  The change I made added a &#8220;guid&#8221; column to the database and uses UUIDTools to generate unique ids instead.&lt;/p&gt;


	&lt;p&gt;I also deleted a bunch of entries that I no longer felt were relevant to the site.  I know a lot of people in the pro-standards crowd don&#8217;t like it when people do this, but I did anyways.  I also tried to set up redirects for all of the old resources to the equivalent URIs in Mephisto, but I&#8217;m sure I missed a couple.  If you bump into a 404 that you think is a mistake on my part, I&#8217;ll try to get it fixed as quickly as possible.&lt;/p&gt;


	&lt;p&gt;In addition to the switch to Mephisto, obviously I also took the time to redesign the site.  I figured I should construct the design entirely from scratch this time instead of simply altering the default Typo theme.  I gotta say, I really, really, really like the new look.  I haven&#8217;t bothered testing and seeing how it looks in Internet Explorer.  I really just don&#8217;t care that much about IE anymore.  But I didn&#8217;t do anything particularly tricky with the design either, so it&#8217;ll probably look mostly OK.  If you&#8217;re reading this in IE, stop, go install some other browser (preferably &lt;a href=&quot;http://getfirefox.com/&quot;&gt;Firefox&lt;/a&gt;), and then come back.  Web developers everywhere will thank you for it.  And you&#8217;ll feel better about yourself.  I promise.&lt;/p&gt;


	&lt;p&gt;I released a new library the other day called &lt;a href=&quot;http://rubyforge.org/projects/squish/&quot;&gt;Squish&lt;/a&gt;.  Admittedly, in its current state, it&#8217;s really effectively useless.  I&#8217;ve never been particularly good at optimizing for performance, and while I did manage to improve the speed of the library (with the help of people in #ruby-lang) by at least an order of magnitude, it&#8217;s still way too slow to be useful.  In retrospect, I&#8217;m not really sure why I even tried to write it in Ruby&#8212;I really should have known that a compression-based text classifier would need to be written in C.  But hey, at least I know the basic idea works now.&lt;/p&gt;


	&lt;p&gt;Oh, and you may also notice that the site is faster and less error-prone now.  You can thank &lt;a href=&quot;http://slicehost.com/&quot;&gt;Slicehost&lt;/a&gt; for that.  I can&#8217;t recommend them highly enough if you&#8217;re in the market for a Rails-friendly &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt; host.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:d9b12c78-6bc8-4802-93ae-b0a966b5ed7c</id>
    <published>2007-03-16T22:43:04Z</published>
    <updated>2007-04-02T04:23:43Z</updated>
    <category term="randomness"/>
    <category term="uuidtools"/>
    <link href="http://sporkmonger.com/2007/3/16/random-numbers-in-uuidtools" rel="alternate" type="text/html"/>
    <title>Random Numbers in UUIDTools</title>
<summary type="html">&lt;p&gt;I wrote the random number generator for UUIDTools awhile ago, but strangely, I&#8217;m only just now getting around to verifying that the numbers it generates really are decently random.  Previously, I&#8217;d just been &#8220;eyeballing&#8221; it.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I wrote the random number generator for UUIDTools awhile ago, but strangely, I&#8217;m only just now getting around to verifying that the numbers it generates really are decently random.  Previously, I&#8217;d just been &#8220;eyeballing&#8221; it.&lt;/p&gt;
&lt;pre&gt;
~/Projects/Ruby/Components/uuidtools/lib $ irb
UUIDTools environment loaded.
&amp;gt;&amp;gt; output = File.new(&quot;random.txt&quot;, &quot;w&quot;)
=&amp;gt; #&amp;lt;File:random.txt&amp;gt;
&amp;gt;&amp;gt; 10000.times do
?&amp;gt;   output.write(UUID.true_random)
&amp;gt;&amp;gt; end
=&amp;gt; 10000
&amp;gt;&amp;gt; output.close
=&amp;gt; nil
&amp;gt;&amp;gt; exit

~/Projects/Ruby/Components/uuidtools/lib $ ent &amp;lt; random.txt
Entropy = 7.998801 bits per byte.

Optimum compression would reduce the size
of this 160000 byte file by 0 percent.

Chi square distribution for 160000 samples is 266.64, and randomly
would exceed this value 50.00 percent of the times.

Arithmetic mean value of data bytes is 127.1241 (127.5 = random).
Monte Carlo value for Pi is 3.146778669 (error 0.17 percent).
Serial correlation coefficient is -0.000714 (totally uncorrelated = 0.0).
&lt;/pre&gt;

	&lt;p&gt;I&#8217;m reasonably satisfied with that I think.&lt;/p&gt;


	&lt;p&gt;By comparison, the builtin rand method in ruby gets:&lt;/p&gt;


&lt;pre&gt;
~/Projects/Ruby/Components/uuidtools/lib $ rm random.txt
~/Projects/Ruby/Components/uuidtools/lib $ irb
UUIDTools environment loaded.
&amp;gt;&amp;gt; output = File.new(&quot;random.txt&quot;, &quot;w&quot;)
=&amp;gt; #&amp;lt;File:random.txt&amp;gt;
&amp;gt;&amp;gt; 160000.times do
?&amp;gt;   output.write(rand(256).chr)
&amp;gt;&amp;gt; end
=&amp;gt; 160000
&amp;gt;&amp;gt; output.close
=&amp;gt; nil
&amp;gt;&amp;gt; exit

~/Projects/Ruby/Components/uuidtools/lib $ ent &amp;lt; random.txt 
Entropy = 7.998954 bits per byte.

Optimum compression would reduce the size
of this 160000 byte file by 0 percent.

Chi square distribution for 160000 samples is 231.72, and randomly
would exceed this value 75.00 percent of the times.

Arithmetic mean value of data bytes is 127.6154 (127.5 = random).
Monte Carlo value for Pi is 3.150228756 (error 0.27 percent).
Serial correlation coefficient is -0.000933 (totally uncorrelated = 0.0).
&lt;/pre&gt;

	&lt;p&gt;And &lt;a href=&quot;http://random.org/essay.html&quot;&gt;random.org&lt;/a&gt; gets:&lt;/p&gt;


&lt;pre&gt;
Entropy = 7.999805 bits per character.

Optimum compression would reduce the size
of this 1048576 character file by 0 percent.

Chi square distribution for 1048576 samples is 283.61, and randomly
would exceed this value 25.00 percent of the times.

Arithmetic mean value of data bytes is 127.46 (127.5 = random).
Monte Carlo value for PI is 3.138961792 (error 0.08 percent).
Serial correlation coefficient is 0.000417 (totally uncorrelated = 0.0).
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:d1bfd1d7-6893-4db5-8157-d08201585421</id>
    <published>2007-02-19T03:50:52Z</published>
    <updated>2007-04-02T04:23:55Z</updated>
    <category term="ruby"/>
    <link href="http://sporkmonger.com/2007/2/19/instance-variables-class-variables-and-inheritance-in-ruby" rel="alternate" type="text/html"/>
    <title>Instance variables, class variables, and inheritance in Ruby</title>
<content type="html">
            &lt;p&gt;I&#8217;m seeing a lot of code that indicates to me that people don&#8217;t have a complete grasp of when to use class variables in Ruby.&lt;/p&gt;


	&lt;p&gt;Here&#8217;s a quick example script that should give people a better idea of what&#8217;s going on:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;ExampleClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;cv&quot;&gt;@@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;initialize&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.test&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.test&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class=&quot;cv&quot;&gt;@@variable&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;ExampleSubclass&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ExampleClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;cv&quot;&gt;@@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;initialize&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@variable&lt;/span&gt; = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;first_example = &lt;span class=&quot;co&quot;&gt;ExampleClass&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;first_example.test&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;puts &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;second_example = &lt;span class=&quot;co&quot;&gt;ExampleSubclass&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;second_example.test&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Output:&lt;/p&gt;


&lt;pre&gt;
foo
2
baz
---
1
2
3
&lt;/pre&gt;

	&lt;p&gt;Essentially, when you declare a class variable in a base class, it&#8217;s shared with all subclasses.  Changing its value in a subclass will affect the base class and all of its subclasses all the way down the inheritance tree.  This behavior is often exactly what&#8217;s desired.  But equally often, this behavior is not what was intended by the programmer, and it leads to bugs, especially if the programmer did not originally expect for the class to be subclassed by someone else.&lt;/p&gt;


	&lt;p&gt;I strongly encourage Ruby developers to sit down and think about how they want their classes to behave if subclassed by someone else.  Be careful about using class variables, because often what you actually wanted was an instance variable on the class object.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:3b972428-c97d-4981-bf50-a5f264791892</id>
    <published>2007-01-17T20:00:00Z</published>
    <updated>2007-04-02T04:23:47Z</updated>
    <category term="terminal"/>
    <link href="http://sporkmonger.com/2007/1/17/script-generate" rel="alternate" type="text/html"/>
    <title>Script Generate</title>
<content type="html">
            &lt;p&gt;Well, here&#8217;s an interesting mistake I just made.  Went to generate a model for a Rails application I&#8217;m working on, but I made a typo.  Instead of entering:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;script/generate model ListedParts&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;I accidentally typed:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;script generate model ListedParts&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;That of course, didn&#8217;t work.  It just came back with:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;Script started, output file is generate&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Sadly, I was unaware of the functionality of &lt;code&gt;script&lt;/code&gt;, so of course the first thing I did after that was:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;cat generate&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;3 seconds later, my Powerbook was locked hard, and I had a 200 MB file in my directory.&lt;/p&gt;


	&lt;p&gt;Oops.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://sporkmonger.com/">
    <author>
      <name>sporkmonger</name>
    </author>
    <id>urn:uuid:5056154d-2517-4472-a494-823d29abba93</id>
    <published>2007-01-12T23:22:00Z</published>
    <updated>2007-04-02T04:23:50Z</updated>
    <category term="mephisto"/>
    <category term="typo"/>
    <link href="http://sporkmonger.com/2007/1/12/blog-migration" rel="alternate" type="text/html"/>
    <title>Blog Migration</title>
<content type="html">
            &lt;p&gt;Alright, that&#8217;s it.  I&#8217;ve had it.  Just got hit with another hundred or so spammy trackbacks.&lt;/p&gt;


	&lt;p&gt;I&#8217;m sick of Typo.  Too much trackback spam, and no good way of defeating it with Typo.  Typo doesn&#8217;t even let you disable trackbacks.  It has an option for disabling it, but it doesn&#8217;t seem to actually do anything.  Plus regular expressions and simple string blacklists that don&#8217;t match against the poster&#8217;s name, email address, or uri simply aren&#8217;t enough.  It&#8217;s time to migrate to Mephisto.  I&#8217;d been planning on sticking with Typo until GentleCMS was done and then rolling my own setup, but this is much too frustrating.  So yeah, I&#8217;m starting the work required to switch over as of right now.  Might take me a couple days because I have customizations to the Typo codebase, but if you have trouble leaving comments or if the site goes down entirely, you&#8217;ve probably just caught me in the middle of trying something.  And apologies if any comments get lost in the fray.&lt;/p&gt;


	&lt;p&gt;I&#8217;ll probably end up implementing something similar to what Sam Ruby has going because a) it&#8217;s simple and b) seems to work.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Now that I think about it, I might &#8220;reboot&#8221; the design while I&#8217;m at it.  I found my missing spork the other day, so it&#8217;ll likely make a reappearance in the header image for the new design.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; It&#8217;s going to take longer than I thought to get the blog migrated.  In the meantime, I&#8217;ve rather forcibly mangled Typo&#8217;s trackback support by rerouting trackbacks to the homepage.  Didn&#8217;t feel like wading through Typo&#8217;s code when a one line patch to &lt;code&gt;routes.rb&lt;/code&gt; would work.  I&#8217;ll get everything working again later.  The blog conversion has been largely delayed by TextDrive not answering support requests (grr) and by myself being preoccupied with work for a client.  Some cool stuff that I can&#8217;t wait to show off.&lt;/p&gt;
          </content>  </entry>
</feed>
