<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0">
<channel>
<title>dren.ch</title>
<link>http://dren.ch/</link>
<description>dren.ch</description>
<language>en-us</language>
<lastBuildDate>
Sun, 14 Feb 2010 19:12:00 -0600
</lastBuildDate>
<item>
<link>http://dren.ch/shebang-override/</link>
<title>Shebang: What?
</title>
<pubDate>Wed, 04 Nov 2009 23:33:25 -0600</pubDate>
<description>&lt;pre class=&quot;code&quot;&gt;

% /usr/local/php5/bin/php --version
PHP &lt;b&gt;5.2.6&lt;/b&gt; (cli) (built: May 11 2008 13:09:39) 
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
    with Zend Optimizer v3.3.3, Copyright (c) 1998-2007, by Zend Technologies

% echo '&amp;lt;?= phpversion() ?&amp;gt;' | /usr/local/php5/bin/php
&lt;b&gt;5.2.6&lt;/b&gt;

% printf '#!/usr/local/php5/bin/php\n&amp;lt;?= phpversion() ?&amp;gt;' &amp;gt; version
% chmod +x version
% ./version
&lt;b&gt;5.2.6&lt;/b&gt;

% mv version x.php
% ./x.php
&lt;b&gt;4.4.9&lt;/b&gt;

&lt;/pre&gt;

&lt;p&gt;In case you're wondering, this machine is running Linux, not Windows.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;November 6, 2009 update:&lt;/b&gt;
I asked and got a quick answer &lt;a href=&quot;http://serverfault.com/questions/82296/when-do-file-extensions-override-shebang-lines-on-linux&quot;&gt;on serverfault&lt;/a&gt;:
somebody changed &lt;tt&gt;/proc/sys/fs/binfmt_misc/php&lt;/tt&gt;.
&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/perl-module-diff/</link>
<title>modiff: The Perl Module Differ
</title>
<pubDate>Thu, 08 Jan 2009 02:33:40 -0600</pubDate>
<description>&lt;p&gt;
Here's something else I wrote (like
&lt;tt&gt;&lt;a href=&quot;/apache-config-finder/&quot;&gt;acuff&lt;/a&gt;&lt;/tt&gt;) for
working on Apache/Perl installations, particularly unfamiliar ones:
&lt;tt&gt;&lt;a href=&quot;http://github.com/drench/futilities/blob/master/modiff&quot;&gt;modiff&lt;/a&gt;&lt;/tt&gt;, the Perl module differ.
&lt;/p&gt;

&lt;p&gt;
Say you need to update a certain Perl module.
You check out the latest version, make your edits, &amp;quot;make install&amp;quot;,
and everything's great. Usually. Only this time you've just overwritten
a hack that guy who got laid off never committed 6 months ago,
and now everything's broken.
Even rolling back to the previous svn revision can't save you now.
&lt;/p&gt;

&lt;p&gt;You should have run &lt;tt&gt;&lt;a href=&quot;http://github.com/drench/futilities/blob/master/modiff&quot;&gt;modiff&lt;/a&gt;&lt;/tt&gt; first:&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
% cd ~/project/Really-Important-Module &amp;amp;&amp;amp; svn update &amp;amp;&amp;amp; &lt;a href=&quot;http://github.com/drench/futilities/blob/master/modiff&quot;&gt;modiff&lt;/a&gt;
U    lib/Really/Important/Module.pm
Updated to revision 32767.
*** /usr/local/lib/perl5/site_perl/5.8.7/Really/Important/Module.pm   Tue Apr  1 16:59:59 2008
--- lib/Really/Important/Module.pm    Wed Jan  7 20:35:37 2009
***************
*** 2,9 ****

  sub init {
        my $self = shift;
!       # $self-&amp;gt;{conf} = parse_config('/etc/x.conf');
!       # This always bombs. Comment out until I figure out why
        return 1;
  }

--- 2,8 ----

  sub init {
        my $self = shift;
!       $self-&amp;gt;{conf} = parse_config('/etc/x.conf');
        return 1;
  }
&lt;/pre&gt;

&lt;p&gt;
I first wrote &lt;tt&gt;&lt;a href=&quot;http://github.com/drench/futilities/blob/master/modiff&quot;&gt;modiff&lt;/a&gt;&lt;/tt&gt;
in Ruby but I eventually needed to use it on a server that did not have Ruby,
and you probably will too.
The version here is the sensible Perl rewrite.
&lt;/p&gt;

&lt;p&gt;
Note that &lt;tt&gt;&lt;a href=&quot;http://github.com/drench/futilities/blob/master/modiff&quot;&gt;modiff&lt;/a&gt;&lt;/tt&gt;
works only if your module's source is in CPAN-style where *.pm files
are under &lt;tt&gt;lib/&lt;/tt&gt;.
For nonstandard directory layouts or detecting changes to other files like
*.pod or anything XS-related, you're on your own.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;October 5, 2009 update:&lt;/b&gt; modiff is now part of my &lt;a href=&quot;http://github.com/drench/futilities&quot;&gt;&amp;quot;futilities&amp;quot; collection on github&lt;/a&gt;.&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/apache-config-finder/</link>
<title>acuff: Apache Configuration File Finder
</title>
<pubDate>Wed, 16 Jul 2008 14:00:40 -0500</pubDate>
<description>&lt;p&gt;
If you've ever worked on an unfamiliar Apache installation
you know how it is trying to follow all the
includes (which may in turn include more files) to track down
the source of a mysterious rewrite rule or LocationMatch. So I wrote
&lt;tt&gt;&lt;a href=&quot;http://github.com/drench/futilities/blob/master/acuff&quot;&gt;acuff&lt;/a&gt;&lt;/tt&gt;. It searches for an Apache executable
in your &lt;tt&gt;$PATH&lt;/tt&gt; and typical locations like
&lt;tt&gt;/usr/local/apache2/bin&lt;/tt&gt; and spits out its config filenames (with full
paths) to standard output. My typical usage goes something like this:
&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
% &lt;a href=&quot;http://github.com/drench/futilities/blob/master/acuff&quot;&gt;acuff&lt;/a&gt; | xargs grep -il '&amp;lt;location /logout'
/usr/local/etc/apache22/conf/app.conf
&lt;/pre&gt;

&lt;p&gt;
It's in Perl, and anything running Apache is bound to have Perl on it.
It uses no extra CPAN modules but it does need Perl 5 (this being 2008
it's completely reasonable to ignore Perl 4 and earlier, I hope).
Enjoy.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;October 5, 2009 update:&lt;/b&gt; acuff is now part of my &lt;a href=&quot;http://github.com/drench/futilities&quot;&gt;&amp;quot;futilities&amp;quot; collection on github&lt;/a&gt;.&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/js-bloom-filter/</link>
<title>&lt;acronym title=&quot;Excitement Has A New Name&quot;&gt;EHANN&lt;/acronym&gt;: Javascript (and Perl and Ruby) Bloom Filters
</title>
<pubDate>Sat, 11 Aug 2007 09:16:40 -0500</pubDate>
<description>&lt;p&gt;
I've never seen a Javascript
&lt;a href=&quot;http://en.wikipedia.org/wiki/Bloom_filter&quot;&gt;Bloom filter&lt;/a&gt;
implementation &lt;a href=&quot;/js-bloom-filter/bloomfilter.js&quot;&gt;so
I had to write one&lt;/a&gt;, and then had to port it to
&lt;a href=&quot;/js-bloom-filter/bloomfilter.pl.txt&quot;&gt;Perl&lt;/a&gt; and
&lt;a href=&quot;/js-bloom-filter/bloomfilter.rb.txt&quot;&gt;Ruby&lt;/a&gt;.
You'll understand why soon if you don't already.&lt;/p&gt;

&lt;p&gt;Quick aside: more than half of
&lt;a href=&quot;/js-bloom-filter/bloomfilter.js&quot;&gt;&amp;quot;my&amp;quot;
bloomfilter.js&lt;/a&gt; is &lt;a href=&quot;http://pajhome.org.uk/crypt/md5&quot;&gt;somebody
else's BSD-licensed Javascript MD5 library&lt;/a&gt; but you could pretty
easily replace it with some other hash library if you felt the
compulsion.&lt;/p&gt;

&lt;p&gt;I don't think this one would be practical for really large input sets
(like a spell check dictionary built from /usr/dict/words), but I'm sure
you'll think of something if you work at it. Get moving on that.&lt;/p&gt;

&lt;p&gt;To get your brain in gear, here's a small demonstration.&lt;/p&gt;
&lt;p&gt;First, I put the text of a really excellent Wire song (I won't
say which), one word per line (minus punctuation) in a file.
Then using the Ruby version I ran the file through this:
&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;

require 'bloomfilter'

bf = BloomFilter.new({ 'bits' =&amp;gt; 0xff, 'salts' =&amp;gt; %w(z A) })

STDIN.each_line { |l| l.chomp!; bf.add(l.downcase) }

print(b.to_json)

&lt;/pre&gt;

&lt;p&gt;Or maybe I used the Perl one and ran it through this:&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;

require 'bloomfilter.pl'; # what is this, 1994?

my $bf = BloomFilter-&amp;gt;new({ bits =&amp;gt; 0xff, salts =&amp;gt; [qw(z A)] });

while(&amp;lt;&amp;gt;) { chomp; $bf-&amp;gt;add(lc $_); }
print $bf-&amp;gt;as_JSON();

&lt;/pre&gt; 

&lt;p&gt;Doesn't matter. Both give the same output (though I changed the formatting
to make it a little easier to read):&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
{
 &amp;quot;buckets&amp;quot;:[1509645767,990260715,1062483727,150062916,551224088,354022058,1818090233,1463314593,110],
 &amp;quot;bucketsize&amp;quot;:31,
 &amp;quot;bits&amp;quot;:255,
 &amp;quot;salts&amp;quot;:[&amp;quot;z&amp;quot;,&amp;quot;A&amp;quot;]
};
&lt;/pre&gt;

&lt;p&gt;Type some Wire lyrics into the box below and smell the magic:&lt;/p&gt;
&lt;textarea cols=&quot;80&quot; rows=&quot;10&quot; id=&quot;trywords&quot;&gt;&lt;/textarea&gt;
&lt;div id=&quot;bfoutput&quot;&gt;&amp;nbsp;&lt;/div&gt;

&lt;p&gt;The filter check code runs 'onchange' for that text box.
Just type (or paste in) some text, then click outside the box and
you should get some feedback.&lt;/p&gt;
&lt;p&gt;
I encourage you to view the source of this page to see what's really going on
but here's a quick example of the Javascript interface for the impatient:
&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;

// choose an appropriate number of bits and salts
// (don't ask me; you can figure it out)

var bf = new BloomFilter({ bits: 0xffff, salts: ['x','y','z','!'] });

bf.add('one');
bf.add('two');
bf.add('three');

bf.test('one'); // will definitely return true
bf.test('two'); // will definitely return true
bf.test('three'); // will definitely return true

bf.test('eins'); // will probably return false
bf.test('zwei'); // will probably return false
bf.test('drei'); // will probably return false

&lt;/pre&gt;

&lt;p&gt;
If you find bugs in this, please let me know. Also I'd really like to
hear from anyone who finds other cool uses for this (aside from
Wire lyric guessing games). And just to get this
out of the way, I have no idea if this code can interoperate with
the &lt;a href=&quot;http://search.cpan.org/~mceglows/Bloom-Filter-1.0/Filter.pm&quot;&gt;Bloom::Filter module on the CPAN&lt;/a&gt; but I should probably find out.
&lt;/p&gt;

&lt;script src=&quot;/js-bloom-filter/bloomfilter.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
(
	function () {

		var bf;

		var bfsetup = function () {

			bf = new BloomFilter({&quot;buckets&quot;:[1509645767,990260715,1062483727,150062916,551224088,354022058,1818090233,1463314593,110],&quot;bucketsize&quot;:31,&quot;bits&quot;:255,&quot;salts&quot;:[&quot;z&quot;,&quot;A&quot;]});

			var bfo = document.getElementById('bfoutput');
			var twb = document.getElementById('trywords');

			twb.onchange = function () {
				var ins = [], outs = [];
				var words = twb.value.split(/\s+/);
				for (var i=0; i &lt; words.length; ++i) {
					words[i] = words[i].replace(/^\W+/,'').replace(/\W+$/,'');
					if (! words[i].match(/\w/)) continue;
					if (bf.test(words[i].toLowerCase())) ins.push(words[i]);
					else outs.push(words[i]);
				}

				if (! ins.length) ins[0] = &quot;&lt;em&gt;(NONE OF THEM!)&lt;/em&gt;&quot;;
				if (! outs.length) outs[0] = &quot;&lt;em&gt;(NONE OF THEM!)&lt;/em&gt;&quot;;

				bfo.innerHTML = &quot;These words are very probably in &quot; +
					&quot;the Wire song: &lt;b&gt;&quot; + ins.join(&quot;, &quot;) + &quot;&lt;/b&gt;.&lt;br /&gt;&quot; +
					&quot;These words are &lt;em&gt;definitely not&lt;/em&gt; in it: &quot; +
					&quot;&lt;b&gt;&quot; + outs.join(&quot;, &quot;) + &quot;&lt;/b&gt;.&quot;;
			};

		};

		var ool = window.onload;
		if (document.getElementById) { // sorry, no NS/IE &lt; 5
			if (ool) window.onload = function () { ool(); bfsetup() };
			else window.onload = bfsetup;
		}
	}
)();

&lt;/script&gt;
</description>
</item>
<item>
<link>http://dren.ch/perl-Hash-Server/</link>
<title>Hash::Server: a (mostly) memcached-compatible network interface to Perl hashes
</title>
<pubDate>Fri, 01 Jun 2007 13:34:26 -0500</pubDate>
<description>&lt;p&gt;You can
&lt;a href=&quot;/perl-Hash-Server/Hash-Server.tar.gz&quot;&gt;download
Hash::Server here&lt;/a&gt; until I get it
on the &lt;a href=&quot;http://www.cpan.org/&quot;&gt;CPAN&lt;/a&gt; (after a decade with Perl
as my primary programming language I've finally signed up for a PAUSE account,
so it could happen). Maybe you'll find this useful.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;April 29, 2009 update:&lt;/b&gt; this code is now &lt;a href=&quot;http://github.com/drench/Hash-Server/tree/master&quot;&gt;on github&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#synopsis&quot;&gt;SYNOPSIS&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#description&quot;&gt;DESCRIPTION&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#caveats&quot;&gt;CAVEATS&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#see_also&quot;&gt;SEE ALSO&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#author&quot;&gt;AUTHOR&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#copyright_and_license&quot;&gt;COPYRIGHT AND LICENSE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;synopsis&quot;&gt;SYNOPSIS&lt;/a&gt;&lt;/h1&gt;
&lt;pre&gt;
        use Hash::Server ();
        use DB_File (); # for example&lt;/pre&gt;
&lt;pre&gt;
        tie(my %db, 'DB_File', './hash.db') or die $!;&lt;/pre&gt;
&lt;pre&gt;
        Hash::Server-&amp;gt;new({ hash =&amp;gt; \%db, localport =&amp;gt; 11211 })-&amp;gt;Bind();&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;description&quot;&gt;DESCRIPTION&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;While memcached's original purpose was as a networked &lt;em&gt;Memoize&lt;/em&gt;,
it's also a simple way to distribute key/value hashes. But the
official memcached (as the name implies) stores its data in memory,
and is temporary. Given there are so many memcached clients for so many
languages, it seemed a shame that there were no other ``backing
stores'' available.&lt;/p&gt;
&lt;p&gt;This module allows you to distribute any Perl hash structure you like
with the memcached protocol. Typical use would probably involve a
tied hash (as in the &lt;em&gt;DB_File&lt;/em&gt; example above); if you want to serve
a straight untied hash, you might as well use the real memcached,
especially given the limitations of this module...&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;caveats&quot;&gt;CAVEATS&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This module is not a complete implementation of the memcached protocol.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It ignores any expiration times you provide; values are always assumed
permanent.&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;
It ignores any incoming ``flag'' value you provide when storing,
and returns 0 by (default) when getting. Changing $Hash::Server::DEFAULT_FLAG
to another value may help you on the client-side to differentiate a
nonexistent key due to a server outage, or a nonexistent
key because the key just does not exist.
&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;
With standard memcached (flags field aside, which you can't get with the
Perl clients anyway), there is no difference between a nonexistent key and
a down server. For pure caching, that's fine, but your application may need
to know the difference. You can set $Hash::Server::UNDEFINED_KEY to
some value that makes sense to you, such as 0 or q{} (empty string) and
test for that, knowing that if your client returns 'undef',
it means it didn't get that answer from the server.
&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;
The ``stats'' command is unimplemented.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;see_also&quot;&gt;SEE ALSO&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt&quot;&gt;http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt&lt;/a&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;author&quot;&gt;AUTHOR&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Daniel Rench, &amp;lt;&lt;a href=&quot;mailto:citric@cubicone.tmetic.com&quot;&gt;citric@cubicone.tmetic.com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;&lt;a name=&quot;copyright_and_license&quot;&gt;COPYRIGHT AND LICENSE&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Copyright (C) 2007 by Daniel Rench&lt;/p&gt;
&lt;p&gt;This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.7 or,
at your option, any later version of Perl 5 you may have available.&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/flash9-firefox-and-osx/</link>
<title>It might help somebody: Flash 9 with Firefox on a Mac
</title>
<pubDate>Wed, 04 Apr 2007 11:20:51 -0500</pubDate>
<description>&lt;p&gt;When I install Firefox on a Mac, I always
&lt;tt&gt;sudo chown -R 0:0 /Applications/Firefox.app&lt;/tt&gt; after. What, you don't?
But when trying to install Flash 9, I got this:
&lt;pre class=&quot;code&quot;&gt;1008:5-5000 Access Denied Error
You do not have enough access privileges for this installation.&lt;/pre&gt;
So I tried running the Flash install as root. Same error.
Then I did this: &lt;tt&gt;sudo chown -R drench /Applications/Firefox.app&lt;/tt&gt;
and ran the install again, which worked, and it made me sad.
&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/html_element_attributes/</link>
<title>Element.getAttribute() doesn't get enough publicity
</title>
<pubDate>Tue, 03 Apr 2007 16:29:58 -0500</pubDate>
<description>&lt;p&gt;
For years I've been using hacks like overloading the &lt;tt&gt;title&lt;/tt&gt; and
&lt;tt&gt;class&lt;/tt&gt; attributes of HTML elements because I didn't know any better.
Now I know I can just make up attributes, like 'regex' here, which I
defined as a pattern that a form field must match:
&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;attributes&amp;lt;/title&amp;gt;
&amp;lt;script&amp;gt;

function make_validator (form) {

	return function () {
		var pat, r;

		for (var i=0, e; e = form[i]; ++i) {

			pat = e.getAttribute('regex');
			if (! pat) continue;

			r = RegExp(pat).exec(e.value);
			if (! r) {
				e.focus();
				alert(&amp;quot;Bad value for &amp;quot; + e.name);
				return false;
			}
		}
		return true;
	};
}

window.onload = function () {

	for (var i=0, form; form=document.forms[i]; ++i)
		form.onsubmit = make_validator(form);

};

&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
&amp;lt;form&amp;gt;
	Number: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;number&amp;quot; regex=&amp;quot;^\d+$&amp;quot;&amp;gt;
	&amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;form&amp;gt;
	Username: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;username&amp;quot; regex=&amp;quot;^\w{1,8}$&amp;quot;&amp;gt;
	&amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
</description>
</item>
<item>
<link>http://dren.ch/rock_bigotry/</link>
<title>We are all bigots / So filled with hatred / We release our poisons
</title>
<pubDate>Tue, 27 Mar 2007 08:47:56 -0500</pubDate>
<description>&lt;p&gt;... like
&lt;a href=&quot;http://kree10.zoomshare.com/1.shtml&quot;&gt;the Bad R&amp;amp;R blog&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;More like &lt;cite&gt;Rock &amp;amp; Roll Bigot&lt;/cite&gt; if you ask me (who,
&amp;quot;full disclosure&amp;quot; is a contributor to the site).&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/unix-command-path-proposal/</link>
<title>Yet another 'radical' idea in Unix file layout
</title>
<pubDate>Mon, 04 Dec 2006 16:47:37 -0600</pubDate>
<description>&lt;p&gt;
Long before &lt;a href=&quot;http://www.securityfocus.com/bid/21185/info&quot;&gt;this
ImageMagick overflow bug&lt;/a&gt; I've been wanting to ditch it completely
in favor of &lt;a href=&quot;http://www.graphicsmagick.org/&quot;&gt;GraphicsMagick&lt;/a&gt;
(still hasn't happened). Aside from the usual bugs, arbitrary API changes
and other endearing quirks, ImageMagick's greatest offense is how its
utility programs have incredibly generic names like &lt;tt&gt;display&lt;/tt&gt; and
&lt;tt&gt;identify&lt;/tt&gt;.
GraphicsMagick does away with those by running everything through the
&lt;tt&gt;gm&lt;/tt&gt; command, so there's less confusion about what happens when
you type &lt;tt&gt;gm identify somefile.jpg&lt;/tt&gt; as you so often do.
&lt;/p&gt;

&lt;p&gt;
This kind of thing is very common; cvs, svn and openssl (to name a
few that I use often) all fit this pattern.
&lt;a href=&quot;http://www.zsh.org/&quot;&gt;Decent shells&lt;/a&gt; are aware of these
programs' &amp;quot;subcommands&amp;quot; and will tab-complete them for you.
But the chances that your shell's tab completion is an exact match with
whatever version of, say, svn you're running are low. Maybe svn added a
new command, but your shell completion doesn't know about it yet. Or
maybe your shell completion has all the latest updates but you're
stuck running an old version of svn that doesn't have it, allowing your
tab completion to taunt you.
&lt;/p&gt;

&lt;p&gt;
Imagine then if your shell was smart enough to detect directories in
&lt;tt&gt;$PATH&lt;/tt&gt; entries and gave them special treatment, looking for
&amp;quot;subcommands&amp;quot; under them.
Then svn could install itself under a directory called
&lt;tt&gt;/usr/local/bin/svn/&lt;/tt&gt;, where you'd have
&lt;tt&gt;/usr/local/bin/svn/checkout&lt;/tt&gt;, 
&lt;tt&gt;/usr/local/bin/svn/commit&lt;/tt&gt;,
&lt;tt&gt;/usr/local/bin/svn/log&lt;/tt&gt;, etc.
Instead of &lt;tt&gt;svn checkout&lt;/tt&gt; you would run &lt;tt&gt;svn/checkout&lt;/tt&gt;.
And with a link from &lt;tt&gt;checkout&lt;/tt&gt; to &lt;tt&gt;co&lt;/tt&gt; you would still
have your &lt;tt&gt;svn co&lt;/tt&gt; shortcut.
The commands themselves wouldn't necessarily need to look different;
the shell could automatically translate &lt;tt&gt;svn co&lt;/tt&gt; to &lt;tt&gt;svn/co&lt;/tt&gt;
for you and you might not even realize anything changed.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Anonymous commentor made all kinds of good points
(particularly about just using something like &amp;quot;gm-&lt;i&gt;whatever&lt;/i&gt;&amp;quot;)
so this is a &amp;quot;nevermind&amp;quot;.&lt;/p&gt;
</description>
</item>
<item>
<link>http://dren.ch/inexplicably-popular/</link>
<title>The inexplicable popularity differences of two photos
</title>
<pubDate>Mon, 30 Oct 2006 16:35:48 -0600</pubDate>
<description>&lt;p style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;http://flickr.com/photos/drench/270871302/&quot; title=&quot;The inexplicably popular photo&quot;&gt;&lt;img src=&quot;http://static.flickr.com/108/270871302_97bb7fa77e_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Changing the diaper on the pretend baby&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I realize that by linking to this photo I'm only making things worse,
but why is the photo above among my top-viewed
&lt;a href=&quot;http://flickr.com/photos/drench&quot;&gt;flickr pictures&lt;/a&gt;?
And why is the one below one of the very least popular?
It's among my favorites, but not yours? What's your problem?&lt;/p&gt;
&lt;p style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;http://flickr.com/photos/drench/89529425/&quot; title=&quot;The inexplicably unpopular photo&quot;&gt;&lt;img src=&quot;http://static.flickr.com/16/89529425_2ca48d6319_m.jpg&quot; width=&quot;180&quot; height=&quot;240&quot; alt=&quot;Lemon #17&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
</item>
</channel></rss>