<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blackkettle</title>
	<atom:link href="http://blog.blackkettle.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.blackkettle.org</link>
	<description>Things of Occasional Interest</description>
	<lastBuildDate>Wed, 10 Feb 2010 16:03:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Quick quine</title>
		<link>http://blog.blackkettle.org/2010/02/10/quick-quine/</link>
		<comments>http://blog.blackkettle.org/2010/02/10/quick-quine/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 16:03:09 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/2010/02/10/quick-quine/</guid>
		<description><![CDATA[Shorter than my old version, this erb quine is 68 characters long:
&#60;%=s=";\"&#60;%=s=\#{s.inspect}\#{s}%\\&#62;\"";"&#60;%=s=#{s.inspect}#{s}%\&#62;"%&#62;
]]></description>
			<content:encoded><![CDATA[<p>Shorter than my old version, this erb quine is 68 characters long:</p>
<pre><code>&lt;%=s=";\"&lt;%=s=\#{s.inspect}\#{s}%\\&gt;\"";"&lt;%=s=#{s.inspect}#{s}%\&gt;"%&gt;</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2010/02/10/quick-quine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[ANN] CL-Twitter</title>
		<link>http://blog.blackkettle.org/2010/01/29/ann-cl-twitter/</link>
		<comments>http://blog.blackkettle.org/2010/01/29/ann-cl-twitter/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 00:04:31 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/2010/01/29/ann-cl-twitter/</guid>
		<description><![CDATA[CL-Twitter is here, for (some of) your lispish twittery needs. Or it will be, once the code is in a usable state.
Right now you can load twitter.lisp into a REPL and make, delete, list posts, and so on, but it&#8217;s broken as an asdf package. I&#8217;ll fix that later &#8211; right now this is more [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/regularfry/cl-twitter">CL-Twitter</a> is here, for (some of) your lispish twittery needs. Or it will be, once the code is in a usable state.</p>
<p>Right now you can load twitter.lisp into a REPL and make, delete, list posts, and so on, but it&#8217;s broken as an asdf package. I&#8217;ll fix that later &#8211; right now this is more proof-of-concept stuff while I learn how CL works.</p>
<p>It&#8217;s tested in Clozure, but the heavy lifting is all done in drakma and cl-json.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2010/01/29/ann-cl-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CLBuild rocks.</title>
		<link>http://blog.blackkettle.org/2010/01/27/clbuild-rocks/</link>
		<comments>http://blog.blackkettle.org/2010/01/27/clbuild-rocks/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 00:26:29 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=119</guid>
		<description><![CDATA[It does. I&#8217;m not entirely it&#8217;s an active project these days, but I&#8217;ve been using it to get up and running with clozure. Getting clbuild to work with clozure involved a bit of jiggery-pokery, however. Basically what I needed to do was:

Switch the svn url in implementations to point to an architecture-specific release
./clbuild update ccl
Manually [...]]]></description>
			<content:encoded><![CDATA[<p>It does. I&#8217;m not entirely it&#8217;s an active project these days, but I&#8217;ve been using it to get up and running with <a href="http://trac.clozure.com/ccl">clozure</a>. Getting <a href="http://common-lisp.net/project/clbuild/">clbuild</a> to work with clozure involved a bit of jiggery-pokery, however. Basically what I needed to do was:</p>
<ul>
<li>Switch the svn url in <code>implementations</code> to point to an architecture-specific release</li>
<li><code>./clbuild update ccl</code></li>
<li>Manually (re)build ccl</code></li>
<li>Put the following into <code>clbuild.conf</code>:
<pre><code>DEFAULT_LISP_IMPLEMENTATION=ccl
CCL=/home/alex/clbuild/source/ccl/lx86cl64</code></pre>
</li>
</ul>
<p>...and that's it. <code>./clbuild slime</code> does what I want, and I haven't found anything that breaks <code>./clbuild install</code> yet.</p>
<p>I'm cutting my teeth on a twitter client library (because yes, the world <b>does</b> need another one, damnit) which I will either a) post to <a href="http://github.com/regularfry">github</a>, or b) bury under the blissful outpourings of /dev/rand.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2010/01/27/clbuild-rocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[ANN] main.py</title>
		<link>http://blog.blackkettle.org/2010/01/27/ann-main-py/</link>
		<comments>http://blog.blackkettle.org/2010/01/27/ann-main-py/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 23:56:52 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=115</guid>
		<description><![CDATA[Well, all I can say is that I hope I&#8217;m not treading on anyone else&#8217;s namespace with my little effort.
I finally got bored with rolling and re-rolling my own command line processors in Python, so I&#8217;ve knocked together a little something to make things simpler for myself.
It&#8217;s loosely based on the marvellously prolific Ara T. [...]]]></description>
			<content:encoded><![CDATA[<p>Well, all I can say is that I hope I&#8217;m not treading on anyone else&#8217;s namespace with my little effort.</p>
<p>I finally got bored with rolling and re-rolling my own command line processors in Python, so I&#8217;ve knocked together <a href="http://github.com/regularfry/mainpy">a little something</a> to make things simpler for myself.</p>
<p>It&#8217;s loosely based on the marvellously prolific Ara T. Howard&#8217;s <a href="http://codeforpeople.com/lib/ruby/main/main-2.8.3/">main</a> gem, but it doesn&#8217;t have nearly the feature set. Yet. I guess I&#8217;ve given myself something to aim for there.</p>
<p>Anyhow, here&#8217;s how to use it, nicked straight from the README:</p>
<pre><code>
import main
import sys

def callback(params):
  print "Called with " + params['foo'].value

m = main.mode("run", callback)
m.option("foo")
m.description="How not to be seen"
main.process(sys.argv)

</code></pre>
<p>Called as:</p>
<pre><code>$ python b.py</code></pre>
<p>Outputs:</p>
<pre><code>Usage:
  # How not to be seen
        b.py run --foo=&lt;foo&gt;</code></pre>
<p>Called as:</p>
<pre><code>$ python b.py run --foo=bar</code></pre>
<p>Outputs:</p>
<pre><code>Called with bar</code></pre>
<p>There&#8217;s lots left to do (decent error handling, for instance &#8211; it makes a modicum of effort, but largely you can expect mistakes to blow up in your face), but it&#8217;s a start.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2010/01/27/ann-main-py/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby and NekoHTML</title>
		<link>http://blog.blackkettle.org/2010/01/27/jruby-and-nekohtml/</link>
		<comments>http://blog.blackkettle.org/2010/01/27/jruby-and-nekohtml/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 23:33:55 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=112</guid>
		<description><![CDATA[My last post (from ages ago) dealt with creating a parser wrapped around celerity. That approach has since stopped working because of API changes, so I figured I might as well see about doing it properly by directly talking to NekoHTML, which is the parser underlying HtmlUnit. If you install celerity, you get the nekohtml [...]]]></description>
			<content:encoded><![CDATA[<p>My last post (from ages ago) dealt with creating a parser wrapped around <a href="http://celerity.rubyforge.org">celerity</a>. That approach has since stopped working because of API changes, so I figured I might as well see about doing it properly by directly talking to <a href="http://nekohtml.sourceforge.org">NekoHTML</a>, which is the parser underlying HtmlUnit. If you install celerity, you get the nekohtml jar anyway, so I figured I might as well try to make some sort of use of it.</p>
<p>Because I&#8217;m not so familiar with the Java XML APIs, this took me more hunting than I expected, but I&#8217;ve wrapped it up in a gem for posterity.</p>
<p>In other words: ew. <a href="http://github.com/regularfry/nekohtml">This code is icky but (possibly) useful.</a></p>
<pre><code>
require 'nekohtml'
html = "&lt;html&gt;&lt;head&gt;&lt;title&gt;Title of Majesty&lt;/title&gt;&lt;/head&gt;&lt;/html&gt;"
Nekohtml.parse(html).at("//TITLE").text
 # => "Title of Majesty"
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2010/01/27/jruby-and-nekohtml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[ANN] celerity_parser 0.1.1</title>
		<link>http://blog.blackkettle.org/2009/06/22/ann-celerity_parser-011/</link>
		<comments>http://blog.blackkettle.org/2009/06/22/ann-celerity_parser-011/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 07:22:14 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=103</guid>
		<description><![CDATA[HTML parsing in JRuby seems to be going through a slightly odd patch. Nokogiri and Hpricot both seem to have problems. There&#8217;s one project I&#8217;m working on at the moment which needs xpath support, and by chance I happen to be using Celerity, which wraps htmlunit. If I need an HTML parser, I thought, there [...]]]></description>
			<content:encoded><![CDATA[<p>HTML parsing in JRuby seems to be going through a slightly odd patch. Nokogiri and Hpricot both seem to have problems. There&#8217;s one project I&#8217;m working on at the moment which needs xpath support, and by chance I happen to be using <a href="http://celerity.rubyforge.org">Celerity</a>, which wraps <a href="http://htmlunit.sourceforge.net">htmlunit</a>. If I need an HTML parser, I thought, there must be one somewhere hidden within that I can use. For extra bonus points, I wouldn&#8217;t even need to package any native code, celerity already has that covered&#8230;</p>
<p><a href="http://github.com/regularfry/celerity_parser/tree/master">And so it came to pass.</a> celerity_parser is an almost trivially thin wrapper around HtmlUnit&#8217;s HTMLParser class that&#8217;s got <i>just</i> enough functionality to do what I need, which is search for elements by xpath, and extract text and XHTML structure. When I say &#8220;trivially thin&#8221;, I really mean it &#8211; there&#8217;s a grand total of 2 Ruby classes, and 5 methods you might want to use.</p>
<p>Here&#8217;s how it works, taken from the README:</p>
<pre><code>
root_node = CelerityParser.parse(html_content)
found_elements = root_node.search("//html/head/title")
found_elements.first.text # => "Html page title"
</code></pre>
<p>That&#8217;s pretty much it. Dependencies are on jarib-celerity and jruby itself. Enjoy, and I&#8217;m open to pull requests and suggestions if you need more than this. I&#8217;ve not done any speed tests, but it&#8217;s native Java so might be quite nippy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2009/06/22/ann-celerity_parser-011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Rails Environments</title>
		<link>http://blog.blackkettle.org/2009/06/03/custom-rails-environments/</link>
		<comments>http://blog.blackkettle.org/2009/06/03/custom-rails-environments/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 18:59:52 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=100</guid>
		<description><![CDATA[It&#8217;s slightly more involved than you might think to make a custom Rails environment that is based on another. In my case, I wanted to have a staging environment that was as close as possible to production. So, I thought require 'config/environment/production' should do the trick.
Not so.
Because of the config.foo magic and the fact that [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s slightly more involved than you might think to make a custom Rails environment that is based on another. In my case, I wanted to have a staging environment that was as close as possible to production. So, I thought <code>require 'config/environment/production'</code> should do the trick.</p>
<p>Not so.</p>
<p>Because of the config.foo magic and the fact that it requires binding tomfoolery, environments aren&#8217;t loaded, or loadable, with require. They&#8217;re read and eval&#8217;d. Here&#8217;s what I&#8217;ve got at the top of <code>config/environment/staging.rb</code> at the moment:</p>
<pre><code>
production_environment_path = File.join(File.dirname(configuration.environment_path), 'production.rb')
eval(IO.read(production_environment_path), binding, production_environment_path)
</code></pre>
<p>So far so good. I&#8217;ll update here if that turns out not to be the whole story.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2009/06/03/custom-rails-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best explanation of monads I&#8217;ve seen yet</title>
		<link>http://blog.blackkettle.org/2009/05/14/best-explanation-of-monads-ive-seen-yet/</link>
		<comments>http://blog.blackkettle.org/2009/05/14/best-explanation-of-monads-ive-seen-yet/#comments</comments>
		<pubDate>Thu, 14 May 2009 07:50:47 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=98</guid>
		<description><![CDATA[I stumbled on this today. I don&#8217;t know why, but I&#8217;ve always had a block over what the word &#8220;monad&#8221; actually means, and how the bind and return operations map to that meaning.
In the linked StackOverflow post, there is a single sentence that fixes the problem:
An alternative term is computation builder which is a bit [...]]]></description>
			<content:encoded><![CDATA[<p>I stumbled on <a href="http://stackoverflow.com/questions/44965/what-is-a-monad">this</a> today. I don&#8217;t know why, but I&#8217;ve always had a block over what the word &#8220;monad&#8221; actually means, and how the bind and return operations map to that meaning.</p>
<p>In the linked StackOverflow post, there is a single sentence that fixes the problem:</p>
<blockquote><p>An alternative term is computation builder which is a bit more descriptive of what they are actually useful for.</p></blockquote>
<p>Ah-ha! The rest of the post is made up of some great examples. Go read if you&#8217;re as confused as I was.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2009/05/14/best-explanation-of-monads-ive-seen-yet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Client uploads to Amazon S3</title>
		<link>http://blog.blackkettle.org/2009/05/05/client-uploads-to-amazon-s3/</link>
		<comments>http://blog.blackkettle.org/2009/05/05/client-uploads-to-amazon-s3/#comments</comments>
		<pubDate>Tue, 05 May 2009 17:24:38 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=95</guid>
		<description><![CDATA[As part of the spangly new and exciting project I&#8217;m working on, I&#8217;ve got a dumb JRuby client app that runs on the user&#8217;s desktop, which I need to have upload data to my S3 buckets. I pondered and read for a bit. S3 is new to me, so I was wandering off down the [...]]]></description>
			<content:encoded><![CDATA[<p>As part of the spangly new and exciting project I&#8217;m working on, I&#8217;ve got a dumb JRuby client app that runs on the user&#8217;s desktop, which I need to have upload data to my S3 buckets. I pondered and read for a bit. S3 is new to me, so I was wandering off down the path of &#8220;touch the key with a public-writeable ACL, wait for a completion notification callback, then close the ACL.&#8221; This, obviously, is madness.</p>
<p>Luckily, the fine folks at Amazon have already thought of this, and provided a POST mechanism designed for browsers. It&#8217;s got a slightly strange gotcha, though: the uploaded file must be the last element in the POST body. This and Ruby&#8217;s default Net::HTTP API sent me looking for alternatives to building the post by hand.</p>
<p>The solution is quite neat. I&#8217;ve got a teeny Sinatra app sitting on the server whose only purpose is to serve prevalidated upload forms to authenticated clients. Auth is provided by Rack. The client just uses 6 lines of Mechanize code to fill in the form details and submit it to S3. It&#8217;s rather a library-heavy solution, but as a concept it doesn&#8217;t get much simpler.</p>
<p>And simpler is better.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2009/05/05/client-uploads-to-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Current Rails template</title>
		<link>http://blog.blackkettle.org/2009/05/05/current-rails-template/</link>
		<comments>http://blog.blackkettle.org/2009/05/05/current-rails-template/#comments</comments>
		<pubDate>Tue, 05 May 2009 08:43:24 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.blackkettle.org/?p=93</guid>
		<description><![CDATA[For reference, here&#8217;s my standard Rails kit at the moment:

Authlogic for session handling.
Paperclip for uploads.
RestClient for remote service handling.
Mocha for mocking.
Webrat for integration testing.
Scaffolding_extensions for laziness.
Passenger/Apache for serving.
Vlad for deployment.

I want to add cucumber and thin to this, but cucumber has given me problems in the past and I just haven&#8217;t got round to trying [...]]]></description>
			<content:encoded><![CDATA[<p>For reference, here&#8217;s my standard Rails kit at the moment:</p>
<ul>
<li>Authlogic for session handling.</li>
<li>Paperclip for uploads.</li>
<li>RestClient for remote service handling.</li>
<li>Mocha for mocking.</li>
<li>Webrat for integration testing.</li>
<li>Scaffolding_extensions for laziness.</li>
<li>Passenger/Apache for serving.</li>
<li>Vlad for deployment.</li>
</ul>
<p>I want to add cucumber and thin to this, but cucumber has given me problems in the past and I just haven&#8217;t got round to trying thin out yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blackkettle.org/2009/05/05/current-rails-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
