<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-13964332</id><updated>2011-12-14T19:05:07.757-08:00</updated><category term='ruby'/><category term='Perl'/><category term='DBI'/><category term='refactoring'/><category term='IDE'/><category term='CPAN'/><title type='text'>Two Alpha</title><subtitle type='html'>Random musing on software, mostly.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>87</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-13964332.post-8837351790644846420</id><published>2010-10-06T08:36:00.001-07:00</published><updated>2010-10-06T08:37:40.339-07:00</updated><title type='text'>Just Kids: A story of two young people becoming Artists</title><content type='html'>&lt;a href="http://www.pattismith.net/" title="Patti Smith's web site"&gt;Patti Smith&lt;/a&gt;'s recent book "Just Kids" is a wonderfully told story of two young people (Smith and &lt;a href="http://www.mapplethorpe.org/" title="Robert Mapplethorpe Foundation"&gt;Robert Mapplethorpe&lt;/a&gt;) pursuing their dreams and becoming Artists. The story is told in Smith's customary tender fierceness - qualities which we can absorb and future in ourselves as we read along. I highly recommend this book to anyone interested in artistic processes.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0062014951?ie=UTF8&amp;amp;tag=levity&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0062014951" title="Just Kids - Limited Edition on Amazon.com"&gt;Just Kids on Amazon&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/art" rel="tag"&gt;art&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/artist" rel="tag"&gt;artist&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-8837351790644846420?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/8837351790644846420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=8837351790644846420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8837351790644846420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8837351790644846420'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2010/10/just-kids-story-of-two-young-people.html' title='Just Kids: A story of two young people becoming Artists'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-54722883501223205</id><published>2010-03-06T07:49:00.000-08:00</published><updated>2010-03-06T07:50:12.089-08:00</updated><title type='text'>RPC - How can you be two places at once when you're not anywhere at all?</title><content type='html'>Recently I've been looking into using either XML-RPC or JSON-RPC to communicate between a Cocoa client and a PHP back-end.&lt;br /&gt;&lt;br /&gt;I came across Samuel Sutch's &lt;a href="http://samuraiblog.com/wordpress/2009/11/06/json-rpc-in-objective-c/trackback/" title="JSON-RPC in Objective-C"&gt;Objective-C implementation of JSON-RPC&lt;/a&gt; and saw what to me is a curious pattern: methods with no name that take any object (id) as an argument and return an object of indeterminate type (id)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:monospace;font-size:11pt;"&gt;- (&lt;/span&gt;&lt;span style="font-family:monospace;color:#aa0d91;font-size:11pt;"&gt;id&lt;/span&gt;&lt;span style="font-family:monospace;font-size:11pt;"&gt;):(&lt;/span&gt;&lt;span style="font-family:monospace;color:#aa0d91;font-size:11pt;"&gt;id&lt;/span&gt;&lt;span style="font-family:monospace;font-size:11pt;"&gt;)arg {&lt;br /&gt;  // do stuff&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;While this is legal in Objective-C it sure is difficult for me to follow. That said, I'm not an expert in ObjC so I consider this a learning opportunity.&lt;br /&gt;&lt;br /&gt;I suspect that the reasoning behind this has something to do with the fact that the author is implementing a version of the &lt;a href="http://twistedmatrix.com/documents/current/core/howto/defer.html" title="Deferred docs at twistedmatrix.com"&gt;"Deferred" pattern&lt;/a&gt;. Still, it seems like code that is very hard to maintain. I'm hoping to get in touch with the author and learn more. At a minimum I hope to become better educated.&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Mac OS X" rel="tag"&gt;Mac OS X&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/Objective-C" rel="tag"&gt;Objective-C&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/open source" rel="tag"&gt;open source&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-54722883501223205?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/54722883501223205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=54722883501223205' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/54722883501223205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/54722883501223205'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2010/03/rpc-how-can-you-be-two-places-at-once.html' title='RPC - How can you be two places at once when you&amp;#39;re not anywhere at all?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-251090358726502514</id><published>2009-07-23T16:35:00.001-07:00</published><updated>2009-07-23T16:35:41.667-07:00</updated><title type='text'>Apple Professional Apps Documentation Goes on the Web</title><content type='html'>The &lt;a href="http://documentation.apple.com/"&gt;complete documentation for Apple's professional apps is now available on the web&lt;/a&gt;.&lt;br /&gt;Links to the individual products are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/appleloopsutility/"&gt;Apple Loops Utility Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/appleqadministrator/"&gt;Apple Qadministrator Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/appleqmaster/"&gt;Apple Qmaster Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/batchmonitor/"&gt;Batch Monitor Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/cinematools/"&gt;Cinema Tools Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/color/"&gt;Color Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/compressor/"&gt;Compressor Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/dvdstudiopro/"&gt;DVD Studio Pro Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/finalcutpro/"&gt;Final Cut Pro Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/finalcutserver/"&gt;Final Cut Server Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/impulseresponseutility/"&gt;Impulse Response Utility Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/logicpro/"&gt;Logic Pro Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/mainstage/"&gt;MainStage Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/motion/"&gt;Motion Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/soundtrackpro/"&gt;Soundtrack Pro Help&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://documentation.apple.com/en/waveburner/"&gt;WaveBurner Help&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-251090358726502514?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/251090358726502514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=251090358726502514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/251090358726502514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/251090358726502514'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2009/07/apple-professional-apps-documentation.html' title='Apple Professional Apps Documentation Goes on the Web'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-622689535994410775</id><published>2009-07-18T13:02:00.001-07:00</published><updated>2009-07-18T13:02:14.001-07:00</updated><title type='text'>Josh Keppel reviews some Oakland California Burning Man cultural
spin-offs</title><content type='html'>Flamethrower SHooting Gallery crew member Josh Keppel is also a writer for NBC Bay Area - a San Francisco Bay Area local news and events web site. &lt;a href="http://www.nbcbayarea.com/around_town/the_scene/From-Beach-to-Burn-West-Oakland-Has-it-All.html"&gt;Josh recently wrote a review of some Oakland-based hot-cultire events&lt;/a&gt;. Have a look.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-622689535994410775?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/622689535994410775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=622689535994410775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/622689535994410775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/622689535994410775'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2009/07/josh-keppel-reviews-some-oakland.html' title='Josh Keppel reviews some Oakland California Burning Man cultural&#xA;spin-offs'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-3529134828215896578</id><published>2009-02-28T09:49:00.001-08:00</published><updated>2009-02-28T09:55:16.754-08:00</updated><title type='text'>Why Technical Debt Should Be More Visible</title><content type='html'>Recently my colleague &lt;a href="http://www.linkedin.com/in/jeffreythalhammer" title="Jeff's Linked-In Profile"&gt;Jeffrey Thalhammer of Imaginative Software&lt;/a&gt; sent me a pointer to Steve McConnell's article on Technical Debt: &lt;a href="http://blogs.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx" title="Link to Article"&gt;http://blogs.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Instead of sending Jeff an email with all my notes, I'm sending him a pointer to this posting.&lt;br /&gt;&lt;br /&gt;Overall I thought the article plus the comments were very good. The comments and back-and-forth really add  a lot of value the the article and I suggest anyone reading the article make their way all the way through the comments.&lt;br /&gt;&lt;br /&gt;I think we should write a version of this aimed entirely at non-technical people.&lt;br /&gt;&lt;br /&gt;McConnell does acknowledge that estimating the "interest payments" is very difficult. One of the (maybe not so obvious?) reasons is that involves calculating the expected lifetime of the system, because as the article says:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;When a system is retired, all of the system's technical debt is retired with it. Once a system has been taken out of production, there's no difference between a "clean and correct" solution and a "quick and dirty" solution.&lt;/em&gt;&lt;/blockquote&gt;So having a realistic estimate of the expected lifetime of the system make a huge difference it the expected cost of the debt.&lt;br /&gt;&lt;br /&gt;I also like the attention that the article and comments gave to the issue of why different people may have different attitudes towards technical debt. For example, the article says:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;The reason most often cited by technical staff for avoiding debt altogether is the challenge of communicating the existence of technical debt to business staff and the challenge of helping business staff remember the implications of the technical debt that has previously been incurred.&lt;br /&gt;&lt;/em&gt;&lt;/blockquote&gt;and commenter Robin Barooah said:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;This might further explain why business people are prepared to accept technical debt - they aren't the ones who are going to have to pay it off.  The developers suffer real consequences because they aren't learning or growing by having to rework code that they knew was being done to substandard quality in the first place.&lt;/em&gt;&lt;/blockquote&gt;I think Barooah's comment is spot-on and indicates an often unarticulated and under appreciated difference between financial and technical debt.&lt;br /&gt;&lt;br /&gt;The article summarizes some of this by saying that:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;The main issue seems to be that, unlike financial debt, technical debt is much less visible, and so people have an easier time ignoring it.&lt;/em&gt;&lt;/blockquote&gt;I would amend that to say "so &lt;strong&gt;some&lt;/strong&gt; people have" cf. Barooah's comment above, but I basically agree: making the "technical debt" more visible is fundamental to improving how it is handled. That means means finding ways to make it visible to people with different perspectives: Finding indicators that are equally meaningful to both business and technical staff would be a big help.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/estimating" rel="tag"&gt;estimating&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-3529134828215896578?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/3529134828215896578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=3529134828215896578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3529134828215896578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3529134828215896578'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2009/02/why-technical-debt-should-be-more.html' title='Why Technical Debt Should Be More Visible'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-1028464013840034902</id><published>2008-09-29T12:15:00.001-07:00</published><updated>2008-10-01T15:39:07.760-07:00</updated><title type='text'>http://documentation.apple.com/ launched.</title><content type='html'>My team launched a&lt;a href="http://documentation.apple.com/" title=" "&gt; website with all the documentation for Final Cut Server&lt;/a&gt; this past Monday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-1028464013840034902?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/1028464013840034902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=1028464013840034902' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/1028464013840034902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/1028464013840034902'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/09/httpdocumentationapplecom-launched.html' title='http://documentation.apple.com/ launched.'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-740583908665464457</id><published>2008-09-23T08:44:00.000-07:00</published><updated>2008-09-23T08:45:09.358-07:00</updated><title type='text'>JavaScript Best Practices, or "JavaScript: The Good Parts"</title><content type='html'>The book, "&lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742%3FSubscriptionId%3D02ZH6J1W0649DTNS6002%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596517742"&gt;JavaScript: The Good Parts&lt;/a&gt;" will be useful to both beginners and experienced JavaScript programmers who want to create better JavaScript code.&lt;br /&gt;&lt;br /&gt;"JavaScript: The Good Parts" is a slim volume (153 pages) that clearly explains a number of best practices for JavaScript giving the "why" and the "how" for dozens of issues such as creating objects, using JSON securely, dealing with regular expressions, &lt;a href="http://www.jslint.com/" title="JSLint web site."&gt;checking your code using JSLint&lt;/a&gt;, and avoiding "attractive nuisances" such as "implied globals." I only wish the author had included something on setting up unit-test frameworks for JavaScript (see for example, &lt;a href="http://github.com/madrobby/scriptaculous/wikis/unit-testing"&gt;Scriptaculous&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;JavaScript is a programming language growing in importance every day - increasingly complex systems such as &lt;a href="http://google.com/gmail/"&gt;GMail&lt;/a&gt;, &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=piazza+il+campo,+italy&amp;amp;ie=UTF8&amp;amp;ll=43.318457,11.3317&amp;amp;spn=0.00537,0.00765&amp;amp;t=h&amp;amp;z=17"&gt;Google Maps&lt;/a&gt;, and &lt;a href="http://www.apple.com/mobileme/"&gt;MobileMe&lt;/a&gt; depend heavily upon it.&lt;br /&gt;The guy who wrote this book, Douglas Crockford, is a "senior JavaScript architect at Yahoo!" and is the fellow who introduced JavaScript Object Notation (JSON) and created JSLint, a JavaScript style-checker (static code analyzer.)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://ecx.images-amazon.com/images/I/51Mb1xCr7CL._SL75_.jpg" /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742%3FSubscriptionId%3D02ZH6J1W0649DTNS6002%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596517742"&gt;"JavaScript: The Good Parts" (Douglas Crockford)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;See also:&lt;br /&gt; &lt;br /&gt;&lt;img src="http://ecx.images-amazon.com/images/I/51lfmfQ79CL._SL75_.jpg" /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Perl-Best-Practices-Damian-Conway/dp/0596001738%3FSubscriptionId%3D02ZH6J1W0649DTNS6002%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596001738"&gt;"Perl Best Practices" (Damian Conway)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/javascript" rel="tag"&gt;javascript&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/static analysis" rel="tag"&gt;static analysis&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-740583908665464457?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/740583908665464457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=740583908665464457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/740583908665464457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/740583908665464457'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/09/javascript-best-practices-or-good-parts.html' title='JavaScript Best Practices, or &amp;quot;JavaScript: The Good Parts&amp;quot;'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4137088953310330814</id><published>2008-09-04T20:35:00.001-07:00</published><updated>2008-09-05T07:50:14.746-07:00</updated><title type='text'>Flamethrower Shooting Gallery Most Dangerous Interactive Installation
on the Playa</title><content type='html'>The &lt;a href="http://www.matisse.net/flamethrower/"&gt;Flamethrower Shooting Gallery&lt;/a&gt; was a big success at Burning Man 2008.&lt;br /&gt;&lt;br /&gt;I asked &lt;a href="http://blog.burningman.com/?author=23"&gt;DaveX&lt;/a&gt; (head of fire safety for the Burning Man organization) for his view and Dave said:&lt;br /&gt;&lt;blockquote&gt;"... heard nothing but good things about how you guys ran it, and I think it's the most dangerous thing out there."&lt;/blockquote&gt;Thanks Dave!&lt;br /&gt;&lt;br /&gt;The Flamethrower Shooting Gallery was the only installation on the playa that combined horizontal flame effects with liquid fuel and was controlled by participants. The fire safety team measured the facial skin temperature on shooters at 130 degrees Fahrenheit&amp;#160; while the flamethrowers were in action.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flickr.com/photos/yegg/2823762847/" title="Shooters preparing to fire."&gt;This photo&lt;/a&gt; shows some shooters getting ready to fire with the assistance of the Range Safety Officers.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Flamethrower Shooting Gallery" rel="tag"&gt;Flamethrower Shooting Gallery&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4137088953310330814?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4137088953310330814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4137088953310330814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4137088953310330814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4137088953310330814'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/09/flamethrower-shooting-gallery-most.html' title='Flamethrower Shooting Gallery Most Dangerous Interactive Installation&#xA;on the Playa'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-458372010059794753</id><published>2008-07-16T22:22:00.001-07:00</published><updated>2008-07-16T22:22:21.652-07:00</updated><title type='text'>Flamethrower Shooting Gallery listed on Laughing Squid</title><content type='html'>A little alternative press coverage at &lt;a href="http://laughingsquid.com/flamethrower-shooting-gallery-by-matisse-roxie/"&gt;Laughing Squid&lt;/a&gt;. Also, here's a bit of &lt;a href="http://www.ktvu.com/video/16839647/index.html" title="KTVU.com"&gt;television news coverage of the Fire Arts Festival&lt;/a&gt;, at &lt;a href="http://www.thecrucible.com/"&gt;The Crucible&lt;/a&gt; where the Flamethrower Shooting Gallery had its world premiere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-458372010059794753?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/458372010059794753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=458372010059794753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/458372010059794753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/458372010059794753'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/07/flamethrower-shooting-gallery-listed-on.html' title='Flamethrower Shooting Gallery listed on Laughing Squid'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-188959479434102270</id><published>2008-06-22T10:55:00.000-07:00</published><updated>2008-06-27T07:41:01.428-07:00</updated><title type='text'>Herb Meyer World Economic Forum Paper could be a Fake</title><content type='html'>Did Herb Meyer really write and/or present the paper attributed to him as having been presented at the World Economic Forum in Davos, Switzerland?&lt;br /&gt;&lt;br /&gt;There are a lot of copies of this paper on the web - variously titled "Four major transformations of the New Century", "A global intelligence briefing for CEOs", etc.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.weforum.org/" title="Web site of the World Economic Forum"&gt;web site of the World Economic Forum&lt;/a&gt; does not seem to contain Herb Meyer's name at all, and certainly &lt;a href="http://www.weforum.org/en/knowledge/contributors/index.htm?alpha=M" title="Alphabetical "&gt;not in the their list of contributers as of late June 2008&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/economics" rel="tag"&gt;economics&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/politics" rel="tag"&gt;politics&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/puppy" rel="tag"&gt;puppy&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-188959479434102270?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/188959479434102270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=188959479434102270' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/188959479434102270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/188959479434102270'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/06/herb-meyer-world-economic-forum-paper.html' title='Herb Meyer World Economic Forum Paper could be a Fake'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-7383962210886227579</id><published>2008-05-26T10:05:00.000-07:00</published><updated>2008-05-26T10:07:35.353-07:00</updated><title type='text'>Modern Web MVC Frameworks</title><content type='html'>It's now mid-2008, and there are a fair number of open source web application frameworks that use the Model-View-Controller approach. They all provide built-in support for automated testing.&lt;br /&gt;&lt;br /&gt;Here is an (incomplete) list of widely used frameworks:&lt;br /&gt;&lt;br /&gt;Groovy&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.grails.org/"&gt;http://www.grails.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Grails_(Framework)"&gt;http://en.wikipedia.org/wiki/Grails_(Framework)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Java&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.springframework.org/"&gt;http://www.springframework.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Spring_Framework"&gt;http://en.wikipedia.org/wiki/Spring_Framework&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Perl&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.catalystframework.org/"&gt;http://www.catalystframework.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Catalyst_(software)"&gt;http://en.wikipedia.org/wiki/Catalyst_(software)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;PHP&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.symfony-project.org/"&gt;http://www.symfony-project.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Symfony"&gt;http://en.wikipedia.org/wiki/Symfony&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Python&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.djangoproject.com/"&gt;http://www.djangoproject.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Django_(web_framework)"&gt;http://en.wikipedia.org/wiki/Django_(web_framework)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Ruby&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.rubyonrails.org/"&gt;http://www.rubyonrails.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Ruby_on_Rails"&gt;http://en.wikipedia.org/wiki/Ruby_on_Rails&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/open source" rel="tag"&gt;open source&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/MVC" rel="tag"&gt;MVC&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/unit tests" rel="tag"&gt;unit tests&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-7383962210886227579?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/7383962210886227579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=7383962210886227579' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7383962210886227579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7383962210886227579'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/05/modern-web-mvc-frameworks.html' title='Modern Web MVC Frameworks'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-7830975214391896336</id><published>2008-02-17T22:49:00.001-08:00</published><updated>2008-02-17T22:49:33.210-08:00</updated><title type='text'>Releasing software under an Open Source License to Increase Business
Value</title><content type='html'>Releasing software under an Open Source License can increase the business value of that software.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why License as Open Source?&lt;/strong&gt;&lt;br /&gt;As a developer when I create software and license it to a customer there are a number of reasons why I might want that license to be an Open Source license. That is, that are a number of ways in which Open Source licenses increase the value of the software to me, the original author. This value points should be weighed against the value created by Closed Source licenses.&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;Open Source Need Not Equal "Free of Charge"&lt;/strong&gt;&lt;br /&gt;Software can be Open Source and fee-for-use and it can be closed-source but free-of-charge.&lt;br /&gt;&lt;br /&gt;Examples:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Embedding the MySQL database in your product: It is Open Source, but you must pay for the right to embed MySQL in your product.&lt;/li&gt;&lt;li&gt;Microsofts' Internet Explorer web browser is free-of-charge but is Closed Source.&lt;/li&gt;&lt;/ul&gt;Releasing software under an Open Source license does not automatically mean you are allowing all use to be free of charge. Indeed, crafting good Open Source fee-for-use licenses is an area of law which would benefit from more creative efforts.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Value From Increased Networking Utility&lt;/strong&gt;&lt;br /&gt;Many of the value propositions listed below derive from the idea of increasing the human networking utility of my software - that is, as under an Open Source license my software can be used to help create and maintain my connections to other people: developers, potential clients, collaborators, pundits, marketers, etc. and a great deal (maybe most?) of the business value available ("Total Value Available") is obtained through connections and relationships, so anything that promotes good connections to other people has potential business value which should be considered.&lt;br /&gt;&lt;br /&gt;Closed Source software licenses act in some ways as barriers to creating and maintaining connections to people. Healthy relationships require boundaries, so this is not a question of all-or-nothing but rather one of degree and kind. A lot of what a Closed Source license does is to try and prevent a loss of value, as opposed to providing utility that can lead to an  increase in value.&lt;br /&gt;&lt;br /&gt;The value that a Closed Source license seeks to create or preserve is based on scarcity and secrecy. The Closed Source License seeks to create a barrier to understanding how the software works, and making it harder for others to reuse or modify the software.   The Closed Source License is addressing the creators' fears that if someone can read the source code they will have an easier time creating a competing product, that it will be easy to copy portions of the code and reuse it without payment and that t will be hard to detect such violations. These are real issues and should be considered before releasing source code in any form.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Specific Kinds of Value Created or Increased by an Open Source License&lt;/strong&gt;&lt;br /&gt;Using an Open Source License for software I create increases its value to me by:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ensuring that I have the right to re-use the software for another project/client.&lt;/li&gt;&lt;li&gt;Increasing the likelihood that my software will be widely used, and thus I will be known to a wider market, and possibly gain market-share and "mind-share."&lt;/li&gt;&lt;li&gt;Increasing the likelihood that my software will be improved. I gain by being associated with the higher-quality experiences the users have, even though some improvements are made by others, as the original author, some of the goodness rubs off on me.&lt;/li&gt;&lt;li&gt;Making it easier to use my software as a marketing tool - I can show the code to prospective clients and collaborators and partners. Increasing the human-networking utility of my software is a&lt;/li&gt;&lt;li&gt;Making it easier to incorporate other Open Source Software into my product, thus giving me a much wider range of options for adding features and making improvements, so I can respond to change requests and new opportunities much faster than if any change had to be implemented &lt;em&gt;de novo&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Providing an effective avenue for the widest possible expert review of the softwares' security. For example, Open Source software that handles vote counting  will likely inspire higher confidence and thus have a greater value.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Some Ideas For Open Source Licenses&lt;br /&gt;&lt;/strong&gt;What can/should one put in a License that is part of a Software Development Contract? I am thinking here of things that specifically relate to adding value for the licensor, for example:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Non-exclusivity. Licensor can use the software for other projects.&lt;/li&gt;&lt;li&gt;Licensor has the right to list the Licensee in marketing materials (e.g. a web site) as a Licensee of the Software.&lt;/li&gt;&lt;li&gt;Prescribing a mechanism for Licensee to "post-back" changes to the software.&lt;/li&gt;&lt;/ul&gt;There are probably a lot more things to consider along these lines - how releasing software as Open Source can increase the softwares' value to the releasor.&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;SEE ALSO&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Some widely used Open Source Licenses:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;apache  &lt;a href="http://apache.org/licenses/LICENSE-2.0"&gt;http://apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;/li&gt;&lt;li&gt;artistic        &lt;a href="http://opensource.org/licenses/artistic-license.php"&gt;http://opensource.org/licenses/artistic-license.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;bsd     &lt;a href="http://www.opensource.org/licenses/bsd-license.php"&gt;http://www.opensource.org/licenses/bsd-license.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;gpl     &lt;a href="http://www.opensource.org/licenses/gpl-license.php"&gt;http://www.opensource.org/licenses/gpl-license.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;lgpl     &lt;a href="http://www.opensource.org/licenses/lgpl-license.php"&gt;http://www.opensource.org/licenses/lgpl-license.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;mit     &lt;a href="http://opensource.org/licenses/mit-license.php"&gt;http://opensource.org/licenses/mit-license.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;mozilla &lt;a href="http://opensource.org/licenses/mozilla1.1.php"&gt;http://opensource.org/licenses/mozilla1.1.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;perl    &lt;a href="http://dev.perl.org/licenses/"&gt;http://dev.perl.org/licenses/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/marketing" rel="tag"&gt;marketing&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/open source" rel="tag"&gt;open source&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-7830975214391896336?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/7830975214391896336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=7830975214391896336' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7830975214391896336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7830975214391896336'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/02/releasing-software-under-open-source.html' title='Releasing software under an Open Source License to Increase Business&#xA;Value'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4508674703486248035</id><published>2008-02-07T06:50:00.001-08:00</published><updated>2008-02-07T06:52:42.897-08:00</updated><title type='text'>Markets are not mathematical creatures.</title><content type='html'>Stock markets look like mathematical phenomena, but they are not. Stock markets are psychological phenomena.&lt;br /&gt;&lt;br /&gt;See "&lt;a href="http://www.amazon.com/Demon-Our-Own-Design-Innovation/dp/0471227277" title="amazon link"&gt;Demon of our own Design&lt;/a&gt;."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4508674703486248035?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4508674703486248035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4508674703486248035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4508674703486248035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4508674703486248035'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2008/02/markets-are-not-mathematical-creatures.html' title='Markets are not mathematical creatures.'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-3009142775048388914</id><published>2007-12-29T01:27:00.001-08:00</published><updated>2008-01-17T08:16:27.053-08:00</updated><title type='text'>BuildBot: Continuous Integration System</title><content type='html'>I've spent some of this holiday season learning how to set up BuildBot (&lt;a href="http://buildbot.net/" title="BuildBot main web site"&gt;http://buildbot.net/&lt;/a&gt;) which is a &lt;a href="http://en.wikipedia.org/wiki/Continuous_Integration" title="Continuous Integration page at Wikipedia"&gt;Continuous Integration&lt;/a&gt; system that is especially aimed at open-source style projects: You set up a central "build master", and one or more "build slaves" - and it is very easy for someone to set up a new build slave, so if you have some new platform you want to test a project on you can add a build slave. The build-master admin has to add your slave on the master side, and the slave needs to be able to access the source code repository (CVS in my case.)&lt;br /&gt;&lt;br /&gt;I've got three of my Perl projects from my CVS repo running under BuildBot now, and it's all working, except email notification of build status - no email is getting to the mail server, and i have yet to learn how to debug that.&lt;br /&gt;&lt;br /&gt;When I commit a change to my CVS repository for one of these projects that kicks off a build on one or more build slaves, which checks out the latest code, and runs all the unit tests. The build master shows the results in a web page.&lt;br /&gt;&lt;br /&gt;I've got about 9.5 hours into it, (out of an initial estimate of 12) include various yak-shaving activities.&lt;br /&gt;&lt;br /&gt;For now I have the build status pages for the three projects at:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://buildbot.eigenstate.net:8010/" title="Perl::Metrics::Simple buildbot page"&gt;Perl-Metrics-Simple&lt;/a&gt; - Building using both MakeMaker and Module::Build. This distro provides modules for a utility program to count lines, packages, subs and complexity of Perl files.&lt;/li&gt;&lt;li&gt;&lt;a href="http://buildbot.eigenstate.net:8020/" title="DBIx::Wrapper::VerySimple buildbot page"&gt;DBIx-Wrapper-VerySimple&lt;/a&gt; - Simplify use of DBI.&lt;/li&gt;&lt;li&gt;&lt;a href="http://buildbot.eigenstate.net:8030/" title="Text::TagTemplate buildbot page"&gt;Text-TagTemplate&lt;/a&gt; - Lightweight flexible template parsing module.&lt;/li&gt;&lt;/ul&gt;See also my &lt;a href="http://twoalpha.blogspot.com/2007/12/continuous-integration-improving.html"&gt;earlier posting with a review of a book on Continuous Integration&lt;/a&gt; and a link to a comparison of several CI systems.&lt;br /&gt;&lt;br /&gt;2007-12-29 update: Starting to add notes to the &lt;a href="http://perl-qa.hexten.net/wiki/index.php/Buildbot" title="BuildBot page on the Perl QA Wiki"&gt;Perl-QA Wiki.&lt;/a&gt;&lt;br /&gt;2008-01-06 update: The email issue was caused by a typo in my master.cfg file.&lt;br /&gt;&lt;code&gt;subject='%(builder) BUILD STATUS',&lt;/code&gt; WRONG&lt;br /&gt;&lt;code&gt;subject='%(builder)s BUILD STATUS',&lt;/code&gt; CORRECT&lt;br /&gt;Note the missing 's' after the closing parenthesis - it is part of a  Python extended printf statement.&lt;br /&gt;Also, I have now added a fourth buildmaster which builds the Parrot project. All my buildbot configurations are now at: &lt;a href="http://www.eigenstate.net/buildbot/masters.html"&gt;http://www.eigenstate.net/buildbot/masters.html&lt;/a&gt;&lt;br /&gt;2008-01-17 update: The open source &lt;a href="http://webkit.org/" title="webkit project home page"&gt;webkit&lt;/a&gt; project uses buildbot - you can see their build status at &lt;a href="http://build.webkit.org/" title="link to webkit build page"&gt;http://build.webkit.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/continuous integration" rel="tag"&gt;continuous integration&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software testing" rel="tag"&gt;software testing&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-3009142775048388914?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/3009142775048388914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=3009142775048388914' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3009142775048388914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3009142775048388914'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/12/buildbot-continuous-integration-system.html' title='BuildBot: Continuous Integration System'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4194725576468078982</id><published>2007-12-01T16:32:00.001-08:00</published><updated>2007-12-30T17:58:14.125-08:00</updated><title type='text'>Continuous Integration - Improving Software Quality and Reducing Risk</title><content type='html'>Paul Duvall, Steve Matyas, and Andrew Glover have written a fine book describing the value and practice of &lt;a href="http://en.wikipedia.org/wiki/Continuous_Integration"&gt;Continuous Integration&lt;/a&gt; or CI for short. If you have heard of CI and want to learn more about it, or if you want to help educate others about it, this book is a very good place to start.&lt;br /&gt;&lt;br /&gt;Continuous Integration is a software development practice intended to notify the development team as soon as possible when a defect is introduced. Typically when CI is being used there is an automated system which the builds the entire project many times each day from its source code to its complete form, and all its automated tests and other automated quality assurance tools can be brought to bear.&lt;br /&gt;&lt;br /&gt;The authors of "Continuous Integration" repeatedly emphasize the role that CI has in reducing risk in software development and constantly provide examples of specific practices that support and benefit from CI, for example frequent commits to a version control system, automated tests,  automated code analysis (test coverage, code complexity, duplication, etc.)&lt;br /&gt;&lt;br /&gt;I think this book would be great for a leader that is trying to convince their team or their management of the value of CI, as well as for a team implementing CI for the first time as an aid to deciding what system to choose and what aspects to implement first.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bookpool.com/sm/0321336380" target="_blank" title="link to Bookpool.com"&gt;Continuous Integration: Improving Software Quality and Reducing Risk&lt;/a&gt;&lt;br /&gt;by Paul Duvall, Steve Matyas, Andrew Glover&lt;br /&gt;Paperback: 336 pages&lt;br /&gt;Publisher: Addison-Wesley Professional (July 9, 2007)&lt;br /&gt;Language: English&lt;br /&gt;ISBN-10: 0321336380&lt;br /&gt;ISBN-13: 978-0321336385&lt;br /&gt;&lt;br /&gt;See also:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Codehause.org has a &lt;a href="http://docs.codehaus.org/display/DAMAGECONTROL/Continuous+Integration+Server+Feature+Matrix" target="_blank" title="link to codehause.org CI comparison matrix"&gt;side-by comparison of many Continuous Integration systems&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://perl-qa.hexten.net/wiki/index.php/Continuous_Integration"&gt;Perl QA Continuous Integration wiki page&lt;/a&gt;.&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/continuous integration" rel="tag"&gt;continuous integration&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/extreme programming" rel="tag"&gt;extreme programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software testing" rel="tag"&gt;software testing&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4194725576468078982?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4194725576468078982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4194725576468078982' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4194725576468078982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4194725576468078982'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/12/continuous-integration-improving.html' title='Continuous Integration - Improving Software Quality and Reducing Risk'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-6228316282035750486</id><published>2007-11-19T19:26:00.001-08:00</published><updated>2007-11-19T19:28:01.164-08:00</updated><title type='text'>Time Machine Very Slow on Leopard</title><content type='html'>Time Machine will run very slowly if an anti-virus utility such as Norton is scanning each file as it is written or changed on the backup disk.&lt;br /&gt;&lt;br /&gt;The fix for this is to go into the Norton Auto-Protect Preference Pane of System Preferences and add your backup disk in the SafeZones tab.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Mac OS X" rel="tag"&gt;Mac OS X&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-6228316282035750486?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/6228316282035750486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=6228316282035750486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/6228316282035750486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/6228316282035750486'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/11/time-machine-very-slow-on-leopard.html' title='Time Machine Very Slow on Leopard'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-8660858800512913499</id><published>2007-09-08T22:44:00.000-07:00</published><updated>2007-09-15T15:32:07.824-07:00</updated><title type='text'>cyradm fails: Can't locate auto/Cyrus/IMAP/imclient_ha.al in @INC</title><content type='html'>Attempting to login via cyradm fails because of a missing library.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;UPDATE 2007-09-15: I believe I have a fix for this. In Cyrus/IMAP/Shell.pm change line 780 from:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p style="text-indent:20pt;"&gt;&lt;span style="font-family:monospace;color:#ff0000;font-size:9pt;"&gt;if (Cyrus::IMAP::imclient_havetls()) {&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;to&lt;/p&gt;&lt;p style="text-indent:20pt;"&gt;&lt;span style="font-family:monospace;color:#ff0000;font-size:9pt;"&gt;if (Cyrus::IMAP::havetls()) {&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;See also: &lt;a href="https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=2988" title="bug report"&gt;https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=2988&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:monospace;font-size:9pt;"&gt;&lt;br /&gt;&lt;/span&gt;Name   : cyrus-imapd&lt;br /&gt;Arch   : x86_64&lt;br /&gt;Version: 2.3.9&lt;br /&gt;Release: 6.fc6&lt;span style="font-family:monospace;font-size:9pt;"&gt;&lt;br /&gt;&lt;br /&gt;$ uname -a&lt;br /&gt;Linux galadriel 2.6.22.1-32.fc6 #1 SMP Wed Aug 1 14:30:16 EDT 2007 x86_64&lt;br /&gt;x86_64 x86_64 GNU/Linux&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:monospace;font-size:9pt;"&gt;$ cyradm&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:monospace;font-size:9pt;"&gt;cyradm&amp;gt; login matisse&lt;br /&gt;Can't locate auto/Cyrus/IMAP/imclient_ha.al in @INC (@INC contains:&lt;br /&gt;/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/site_perl/5.8.7/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/site_perl/5.8.6/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7&lt;br /&gt;/usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5&lt;br /&gt;/usr/lib/perl5/site_perl&lt;br /&gt;/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/vendor_perl/5.8.7/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/vendor_perl/5.8.6/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7&lt;br /&gt;/usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5&lt;br /&gt;/usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi&lt;br /&gt;/usr/lib/perl5/5.8.8 .) at&lt;br /&gt;/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/Cyrus/IMAP/Shell.pm&lt;br /&gt;line 780&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:monospace;font-size:9pt;"&gt;cyradm&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Evidently I am not the only one getting this problem. See: &lt;a href="http://use.perl.org/~jk2addict/journal/32136" title="another users report"&gt;http://use.perl.org/~jk2addict/journal/32136&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-8660858800512913499?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/8660858800512913499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=8660858800512913499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8660858800512913499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8660858800512913499'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/09/cyradm-fails-can-locate.html' title='cyradm fails: Can&amp;#39;t locate auto/Cyrus/IMAP/imclient_ha.al in @INC'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-1149411793424456211</id><published>2007-05-17T23:16:00.001-07:00</published><updated>2007-05-17T23:16:45.494-07:00</updated><title type='text'>Social Dynamics of Pair Programming</title><content type='html'>&lt;a href="http://www.stanford.edu/~jchong/research/chong-icse2007.pdf"&gt;The Social Dynamics of Pair Programming&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Interesting paper by Jan Chong and Tom Hurlbutt at Stanford University.&lt;br /&gt;&lt;br /&gt;Here's the Abstract:&lt;br /&gt;&lt;blockquote&gt;This paper presents data from a four month ethno-&lt;br /&gt;graphic study of professional pair programmers from&lt;br /&gt;two software development teams. Contrary to the cur-&lt;br /&gt;rent conception of pair programmers, the pairs in this&lt;br /&gt;study did not hew to the separate roles of “driver” and&lt;br /&gt;“navigator”. Instead, the observed programmers&lt;br /&gt;moved together through different phases of the task,&lt;br /&gt;considering and discussing issues at the same strategic&lt;br /&gt;“range” or level of abstraction and in largely the same&lt;br /&gt;role. This form of interaction was reinforced by fre-&lt;br /&gt;quent switches in keyboard control during pairing and&lt;br /&gt;the use of dual keyboards. The distribution of expertise&lt;br /&gt;among the members of a pair had a strong influence on&lt;br /&gt;the tenor of pair programming interaction. Keyboard&lt;br /&gt;control had a consistent secondary effect on decision-&lt;br /&gt;making within the pair. These findings have implica-&lt;br /&gt;tions for software development managers and practi-&lt;br /&gt;tioners as well as for the design of software develop-&lt;br /&gt;ment tools.&lt;/blockquote&gt;(&lt;a href="http://www.stanford.edu/~jchong/research/chong-icse2007.pdf" title="PDF Document"&gt;Link to PDF version&lt;/a&gt; or &lt;a href="http://72.14.253.104/search?q=cache:kJVEtrZg4HsJ:www.stanford.edu/~jchong/research/chong-icse2007.pdf+chong-icse2007&amp;amp;hl=en&amp;amp;ct=clnk&amp;amp;cd=1&amp;amp;gl=us&amp;amp;client=firefox-a"&gt;Google HTML view&lt;/a&gt;&lt;span style="color:#1919ff;text-decoration:underline;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/extreme programming" rel="tag"&gt;extreme programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/pair programming" rel="tag"&gt;pair programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/XP" rel="tag"&gt;XP&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-1149411793424456211?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/1149411793424456211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=1149411793424456211' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/1149411793424456211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/1149411793424456211'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/05/social-dynamics-of-pair-programming.html' title='Social Dynamics of Pair Programming'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-3331149056270119785</id><published>2007-05-06T11:23:00.001-07:00</published><updated>2007-05-06T11:23:22.740-07:00</updated><title type='text'>Finding which jar file provides a Java class.</title><content type='html'>Given a class name such as:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;org.springframework.mail.javamail.MimeMessageHelper&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jarfinder.com/" title="Find java classes in jar files"&gt;www.jarfinder.com&lt;/a&gt; provides a fast easy way to find out which .jar file(s) provide the class, with links to the organization and download site for each one.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;br /&gt;  &lt;a href="http://www.jarfinder.com/?class=org.springframework.mail.javamail.SmartMimeMessage&amp;amp;submit=search" title="Example of search-by-class"&gt;http://www.jarfinder.com/?class=org.springframework.mail.javamail.SmartMimeMessage&amp;#38;submit=search&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/java" rel="tag"&gt;java&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-3331149056270119785?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/3331149056270119785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=3331149056270119785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3331149056270119785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3331149056270119785'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/05/finding-which-jar-file-provides-java.html' title='Finding which jar file provides a Java class.'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-2270649998389718898</id><published>2007-04-20T08:54:00.000-07:00</published><updated>2007-04-26T08:01:42.912-07:00</updated><title type='text'>Estimating Value of a Possible Software Project</title><content type='html'>&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;What factors to consider when estimating the value of a possible software project?&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;I made a list various factors I have considered, more or less formally as the case may be, when estimating the value of undertaking a development project.&lt;br /&gt;When I thought about how I measure these factors I found that I generally think of them as each having a probability-distribution.&lt;br /&gt;Instead of "This feature will cut response time in half", something like "This has a 90% chance of getting of cutting response time by 10%, and maybe a 30% chance of cutting it by 60%."&lt;br /&gt;What factors do you find are most worth spending time to consider?&lt;br /&gt;How might you express those factors in making a go/no-go decision on a project?&lt;br /&gt;&lt;br /&gt;Examples, in no particular order:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Value Factors: What will we get from this software?&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt; capabilities - but then I ask, what is the value of each capability?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Wh&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;at is the "total market available" for this software/feature?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;How much of that market can we expect to get?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;What new markets will this get us into?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;What cost(s) will this feature help us avoid or reduce?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;What value does this bring to our team - new skills, experience, etc.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;How much fund will this be?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Synergy with other projects?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;What is the time-to-market value? (what is the value of releasing early vs. later?) Taken to the extreme, that question turns into a cost question: "What is the cost of not releasing at all?"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Reputation value: What value does this bring to our brand?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Cost Factors: What will it cost us?&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Labor costs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Hardware costs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Licensing costs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Costs associated with various risk factors:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Reputation cost for overreaching.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Human cost (burn-out, staff turnover) of doing too much.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;New or increased legal or financial liabilities.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Delay to other projects.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/estimating" rel="tag"&gt;estimating&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-2270649998389718898?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/2270649998389718898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=2270649998389718898' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/2270649998389718898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/2270649998389718898'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/04/estimating-value-of-possible-software.html' title='Estimating Value of a Possible Software Project'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4574515861213530522</id><published>2007-01-21T19:17:00.000-08:00</published><updated>2009-05-01T12:24:37.408-07:00</updated><title type='text'>JUnit-Style XML from Perl Test Files</title><content type='html'>&lt;div style="background-color: lightgrey"&gt;&lt;em&gt;2009-05-01 Update: &lt;a href="http://search.cpan.org/dist/TAP-Harness-JUnit/" title="TAP-Harness-JUnit"&gt;Perl module that provides a test harness that runs TAP tests and outputsJUnit-compatible XML&lt;/a&gt;&lt;/em&gt;&lt;hr /&gt;&lt;/div&gt;&lt;div&gt;Here is an experimental program that runs Perl test files and produces the same sort of XML output as the&lt;a href="http://ant.apache.org/manual/OptionalTasks/junit.html"&gt; &amp;lt;junit&amp;gt; ant task&lt;/a&gt;.Getting this XML output is helpful when running Perl tests under &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt;.&lt;/div&gt;&lt;pre&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use Test::Harness::Straps;&lt;br /&gt;use Time::HiRes qw(gettimeofday tv_interval);&lt;br /&gt;use XML::Generator ':noimport';&lt;br /&gt;&lt;br /&gt;my @files = @ARGV;&lt;br /&gt;&lt;br /&gt;my $strap     = Test::Harness::Straps-&amp;gt;new;&lt;br /&gt;my $generator = XML::Generator-&amp;gt;new(':pretty');&lt;br /&gt;&lt;br /&gt;my @properties = _get_properties($generator);&lt;br /&gt;my $test_results = _run_tests( $strap, $generator, @files );&lt;br /&gt;&lt;br /&gt;my $xml = _get_junit_xml( $generator, \@properties, $test_results );&lt;br /&gt;&lt;br /&gt;print "$xml\n";&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;&lt;br /&gt;#-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;sub _get_junit_xml {&lt;br /&gt;    my ( $generator, $properties, $test_results ) = @_;&lt;br /&gt;&lt;br /&gt;    my $system_out = 'system-out';&lt;br /&gt;    my $system_err = 'system-err';&lt;br /&gt;    my $xml        = '';&lt;br /&gt;    $xml .= "\n";&lt;br /&gt;    $xml .= $generator-&amp;gt;testsuite(&lt;br /&gt;        {&lt;br /&gt;            errors   =&amp;gt; 0,&lt;br /&gt;            failures =&amp;gt; $test_results-&amp;gt;{total_failures},&lt;br /&gt;            name     =&amp;gt; 'name of the test suite',&lt;br /&gt;            tests    =&amp;gt; $test_results-&amp;gt;{total_tests},&lt;br /&gt;            'time'   =&amp;gt; $test_results-&amp;gt;{total_time},&lt;br /&gt;        },&lt;br /&gt;        $generator-&amp;gt;properties(@properties),&lt;br /&gt;        @{ $test_results-&amp;gt;{test_cases} },&lt;br /&gt;        $generator-&amp;gt;$system_out(),&lt;br /&gt;        $generator-&amp;gt;$system_err(),&lt;br /&gt;&lt;br /&gt;    );&lt;br /&gt;    return $xml;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub _run_tests {&lt;br /&gt;    my ( $strap, $generator, @files ) = @_;&lt;br /&gt;    my @test_cases     = ();&lt;br /&gt;    my $total_tests    = 0;&lt;br /&gt;    my $total_time     = 0;&lt;br /&gt;    my $total_failures = 0;&lt;br /&gt;&lt;br /&gt;    foreach my $test_file (@files) {&lt;br /&gt;        my $start_time   = [gettimeofday];&lt;br /&gt;        my $file_results = $strap-&amp;gt;analyze_file($test_file);&lt;br /&gt;        my $elapsed_time = tv_interval( $start_time, [gettimeofday] );&lt;br /&gt;        $total_time += $elapsed_time;&lt;br /&gt;        foreach my $assertion ( @{ $file_results-&amp;gt;details } ) {&lt;br /&gt;            if ( _skip($assertion) ) {&lt;br /&gt;                next;&lt;br /&gt;            }&lt;br /&gt;            $total_tests++;&lt;br /&gt;            $total_failures += _is_failure($assertion);&lt;br /&gt;            my $test_case = {&lt;br /&gt;                classname =&amp;gt; $test_file,&lt;br /&gt;                name      =&amp;gt; $assertion-&amp;gt;{name},&lt;br /&gt;                'time'    =&amp;gt; 0,&lt;br /&gt;            };&lt;br /&gt;            push @test_cases, $generator-&amp;gt;testcase($test_case);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    my $test_results = {&lt;br /&gt;        total_time     =&amp;gt; $total_time,&lt;br /&gt;        test_cases     =&amp;gt; \@test_cases,&lt;br /&gt;        total_tests    =&amp;gt; $total_tests,&lt;br /&gt;        total_failures =&amp;gt; $total_failures,&lt;br /&gt;    };&lt;br /&gt;    return $test_results;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub _skip {&lt;br /&gt;    my $assertion = shift;&lt;br /&gt;    return $assertion-&amp;gt;{type} =~ / skip | todo /x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub _is_failure {&lt;br /&gt;    my $assertion = shift;&lt;br /&gt;    return !$assertion-&amp;gt;{ok};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub _get_properties {&lt;br /&gt;    my $generator  = shift;&lt;br /&gt;    my @properties = ();&lt;br /&gt;    foreach my $key ( sort keys %ENV ) {&lt;br /&gt;        push @properties,&lt;br /&gt;          $generator-&amp;gt;property( { name =&amp;gt; "$key", value =&amp;gt; $ENV{$key} } );&lt;br /&gt;    }&lt;br /&gt;    return @properties;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;__END__&lt;br /&gt;&lt;br /&gt;=head1 NAME&lt;br /&gt;&lt;br /&gt;junit_xml.pl - Run Perl tests and get JUnit-style XML output&lt;br /&gt;&lt;br /&gt;=head1 SYNOPSIS&lt;br /&gt;&lt;br /&gt;   junit_xml.pl file1 [ file2 ... ]&lt;br /&gt;&lt;br /&gt;=head1 DESCRIPTION&lt;br /&gt;&lt;br /&gt;Experimental script to run perl test files and produce the&lt;br /&gt;same XML output as produced by the &amp;lt;junit&amp;gt; ant task.&lt;br /&gt;&lt;br /&gt;=head1 DEPENDENCIES&lt;br /&gt;&lt;br /&gt; Test::Harness&lt;br /&gt; Time::HiRes&lt;br /&gt; XML::Generator &lt;br /&gt;&lt;br /&gt;=head1 BUGS&lt;br /&gt;&lt;br /&gt;  - Doesn't do anything with the STDERR from tests.&lt;br /&gt;  - Doesn't fill in the 'errors' attribute in the  &amp;lt;testsuite&amp;gt; element.&lt;br /&gt;  - Doesn't handle when all tests in file are skipped (skip_all)&lt;br /&gt;  - Doesn't get the elapsed time for each 'test' (i.e. assertion.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;=head1 AUTHOR&lt;br /&gt;&lt;br /&gt;Matisse Enzer &amp;lt;matisse@matisse.net&amp;gt;&lt;br /&gt;&lt;br /&gt;=head1 COPYRIGHT &amp;#38; LICENSE&lt;br /&gt;&lt;br /&gt;Copyright (c) 2007 Matisse Enzer. All Rights Reserved.&lt;br /&gt;&lt;br /&gt;This program is free software; you can redistribute it and/or modify it&lt;br /&gt;under the same terms as Perl itself.&lt;br /&gt;=cut&lt;br /&gt;&lt;/pre&gt;Updates: This post was originally published on 2007-01-21.2008-05-26: I noticed that &lt;a href="http://taint.org/2008/03/26/124602a.html" title="Justin Mason's Weblog"&gt;Justin Mason has created a better script for converting TAP output to JUnit-style XML&lt;/a&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Perl" rel="tag"&gt;Perl&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software testing" rel="tag"&gt;software testing&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4574515861213530522?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4574515861213530522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4574515861213530522' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4574515861213530522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4574515861213530522'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/01/junit-style-xml-from-perl-test-files.html' title='JUnit-Style XML from Perl Test Files'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4651547494241951448</id><published>2007-01-21T12:01:00.001-08:00</published><updated>2007-01-21T14:25:41.607-08:00</updated><title type='text'>Unix shell: Finding the run-time directory of a script</title><content type='html'>I've been trying to come up with an elegant way, in a shell script, to find the full path of the directory in which the script is located.&lt;br /&gt;&lt;br /&gt;So far, I have this, which works for bash but not for sh (sh does not support substring expansion on variables):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; #!/usr/local/bin/bash -x&lt;br /&gt; # Finds the full path to the directory containing this script&lt;br /&gt; &lt;br /&gt; dir_containing_this_script=""&lt;br /&gt; script_dirname=`dirname $0`&lt;br /&gt; first_char="${script_dirname:0:1}" ; # Starting at index 0, 1 character&lt;br /&gt; case "$first_char" in&lt;br /&gt; ("/")&lt;br /&gt;     # It's a full path. Use it unmodified.&lt;br /&gt;     dir_containing_this_script="${script_dirname}"&lt;br /&gt; ;;&lt;br /&gt; (*)&lt;br /&gt;     # Strip leading . characters&lt;br /&gt;     while [ "${first_char}" = "." ]; do&lt;br /&gt;         script_dirname="${script_dirname:1}" ; # substring from index 1 to end&lt;br /&gt;         first_char="${script_dirname:0:1}"&lt;br /&gt;     done&lt;br /&gt;     current_dir=`pwd`&lt;br /&gt;     if [ -s "${script_dirname}" ] ; then&lt;br /&gt;         dir_containing_this_script="${current_dir}/${script_dirname}"&lt;br /&gt;     else &lt;br /&gt;         dir_containing_this_script="${current_dir}"&lt;br /&gt;     fi&lt;br /&gt; ;;&lt;br /&gt; esac&lt;br /&gt; &lt;br /&gt; echo "$dir_containing_this_script"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Update: Eric M on The WELL posted this most excellent solution:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; dn=`dirname $0`&lt;br /&gt; path=`(cd $dn; pwd)`&lt;br /&gt; echo "path = $path"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/unix" rel="tag"&gt;unix&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/unix shell" rel="tag"&gt;unix shell&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4651547494241951448?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4651547494241951448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4651547494241951448' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4651547494241951448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4651547494241951448'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/01/unix-shell-finding-run-time-directory.html' title='Unix shell: Finding the run-time directory of a script'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-8126058477529771520</id><published>2007-01-19T00:05:00.001-08:00</published><updated>2007-01-19T00:13:24.617-08:00</updated><title type='text'>Super Easy Graphics Programming</title><content type='html'>&lt;a href="http://www.allartburns.org/" title="All Art Burns"&gt;Eric Townsend&lt;/a&gt; pointed me to &lt;a href="http://processing.org/" title="Processing Home Page"&gt;Processing&lt;/a&gt; - super easy programming environment for creating graphics programs.&lt;br /&gt;&lt;br /&gt;Here's &lt;a href="http://eigenstate.net/processing_example/" title="Applet Crated with Processing"&gt;an applet I generated from it in a few minutes work,&lt;/a&gt; starting with an example Eric posted on &lt;a href="http://well.com/" title="Applet Crated with Processing"&gt;The WELL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/// start&lt;br /&gt;void setup() {&lt;br /&gt;  size(600,600);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void draw(){&lt;br /&gt;  background(255);&lt;br /&gt;&lt;br /&gt;  int left_x = 0;&lt;br /&gt;  int right_x = width;&lt;br /&gt;  int top_y = 0;&lt;br /&gt;  int bottom_y = height;&lt;br /&gt;  int light_green = #99FF99;&lt;br /&gt;  int light_blue = #66CCFF;&lt;br /&gt;  int light_yellow = #FFCC66;&lt;br /&gt;  int pale_red = #FF3366;&lt;br /&gt;&lt;br /&gt;  for (int n=0; n &amp;lt; 100; n++) {&lt;br /&gt;    int y_of_n = n * (bottom_y/100);&lt;br /&gt;    int x_of_n = n * (right_x/100);&lt;br /&gt;&lt;br /&gt;    stroke(pale_red);&lt;br /&gt;    line(left_x,y_of_n,mouseX,mouseY);&lt;br /&gt;&lt;br /&gt;    stroke(light_yellow);&lt;br /&gt;    line(right_x,y_of_n,mouseX,mouseY);&lt;br /&gt;&lt;br /&gt;    stroke(light_blue);&lt;br /&gt;    line(x_of_n,0,mouseX,mouseY);&lt;br /&gt;&lt;br /&gt;    stroke(light_green);&lt;br /&gt;    line(x_of_n,bottom_y,mouseX,mouseY);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/// end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/graphics" rel="tag"&gt;graphics&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-8126058477529771520?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/8126058477529771520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=8126058477529771520' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8126058477529771520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8126058477529771520'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2007/01/super-easy-graphics-programming.html' title='Super Easy Graphics Programming'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-7951114912976058259</id><published>2006-12-26T21:04:00.000-08:00</published><updated>2006-12-26T21:07:54.050-08:00</updated><title type='text'>Provider Injection, not Dependency Injection</title><content type='html'>The term "provider injection" should replace the term "dependency injection."&lt;br /&gt;&lt;br /&gt;The term misleads by seeming to say that you are "injecting" a dependency. This would mean that the thing got the "dependency" injected into it now depends upon something that it didn't depend upon before. This is not what "dependency injection" means.&lt;br /&gt;&lt;br /&gt;The term "dependency injection" actually means that if Object A depends upon having a "B" object that you "inject" a B object into object A (instead of object A fetching or creating a B on its own.) A classic example would be a Person object that depends upon having a database connection in order to create/update/edit/delete people in the database. Instead of the Person object creating its own database connection it gets one passed to it (i.e. "injected") perhaps as an argument to its constructor. But, see, you are not injecting a &lt;strong&gt;dependency&lt;/strong&gt;. You are injecting a &lt;strong&gt;provider&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;A "dependency" is not the thing upon which you depend. The thing you depend upon is a tool, resource, skill, or capability and you get those things by making them yourself, or from a &lt;strong&gt;provider&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;So, I think the term "&lt;strong&gt;provider injection&lt;/strong&gt;" should replace the term "dependency injection."&lt;br /&gt;&lt;br /&gt;By the way, I want to thank &lt;a href="http://m2ward.blogspot.com/i" title="Mike's blog"&gt;Mike Ward&lt;/a&gt; for originally introducing me to the term "dependency injection" - whatever phrase is used, the actual practice is one I have done in the past and it is good to have a phrase to describe this technique.&lt;br /&gt;&lt;br /&gt;See also:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" title="wikipedia entry"&gt;Wikipedia entry on Dependency Injection&lt;/a&gt; (which I have attempted to edit.)&lt;br /&gt;&lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;Inversion of Control Containers and the Dependency Injection pattern&lt;/a&gt; - 2004 article by &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.springframework.org/node/54"&gt;Spring in Action&lt;/a&gt; - Book on Spring&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/inversion of control" rel="tag"&gt;inversion of control&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-7951114912976058259?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/7951114912976058259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=7951114912976058259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7951114912976058259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/7951114912976058259'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/12/provider-injection-not-dependency.html' title='Provider Injection, not Dependency Injection'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-3219147843432424664</id><published>2006-12-09T15:22:00.000-08:00</published><updated>2006-12-13T21:29:39.058-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>countperl - count lines, packages, subs and complexity of Perl files</title><content type='html'>I recently released a new version of &lt;strong&gt;&lt;a href="http://search.cpan.org/dist/Perl-Metrics-Simple"&gt;Perl::Metrics::Simple&lt;/a&gt;&lt;/strong&gt; (0.03) that includes the &lt;code style="font-style: italic;"&gt;countperl&lt;/code&gt; script. The program reports on how complicated your Perl code is - giving you direction on where to start &lt;a href="http://en.wikipedia.org/wiki/Refactoring"&gt;refactoring&lt;/a&gt; it to make it easier to understand, debug, and maintain. Try to keep the McCabe Complexity at 9 or less for every subroutine and "main" section of your code.&lt;br /&gt;&lt;em&gt;countperl&lt;/em&gt; is a command line tool that you execute with a list of one or more files andor directories. The program examines the named files and recursivesly searches named directories for Perl files.&lt;br /&gt;The &lt;em&gt;countperl&lt;/em&gt; program produces a report on &lt;em&gt;STDOUT&lt;/em&gt; of total lines, packages, subroutines/methods, the minimum, maximum, mean, standard deviation, and median size and mccabe_complexity (aka &lt;a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;cyclomatic complexity&lt;/a&gt;) of subroutines and the 'main' portion of each file (everything not in a subroutine.)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Output Format&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Line counts do not include comments nor pod.&lt;br /&gt;The current output format is human-readable text. For example, a report based on analyzing three files might look like this:&lt;br /&gt;&lt;pre&gt;&lt;span style="color:#666600;"&gt; Perl files found:                3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; Counts&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; ------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; total code lines:       856&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; lines of non-sub code:  450&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; packages found:           3&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; subs/methods:            42&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; Subroutine/Method Size&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; ----------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; min:                  3 lines&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; max:                  32 lines&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; mean:                 9.67 lines&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; std. deviation:       7.03&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; median:               7.50&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; McCabe Complexity&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; -----------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; Code not in any subroutine::&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; min:                  1&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; max                   1&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; mean:                 1.00&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; std. deviation:       0.00&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; median:               1.00&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; Subroutines/Methods:&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; min:                  1&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; max:                  5&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; avg:                  1.00&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; std. deviation:       1.36&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; median:               1.00&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; Tab-delimited list of subroutines, with most complex at top&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; -----------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; complexity      sub     path    size&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 5       is_perl_file    lib/Perl/Metrics/Simple.pm      11&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 5       _has_perl_shebang       lib/Perl/Metrics/Simple.pm      13&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 5       _init   lib/Perl/Metrics/Simple/Analysis/File.pm        30&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 4       find_files      lib/Perl/Metrics/Simple.pm      11&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 4       new     lib/Perl/Metrics/Simple/Analysis.pm     10&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#666600;"&gt; 4       is_ref  lib/Perl/Metrics/Simple/Analysis.pm     8&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Chris Chedgey has a posting that describes a common situation - you have &lt;a href="http://chris.headwaysoftware.com/2006/10/reducing_comple.html" title="Complexity Debt - don't fix it - keep a lid on it"&gt;accumulated a huge pile of "complexity debt"&lt;/a&gt; - well, using &lt;strong&gt;countperl&lt;/strong&gt; is one tool to help "keep a lid on it."&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Perl" rel="tag"&gt;Perl&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/refactoring" rel="tag"&gt;refactoring&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software testing" rel="tag"&gt;software testing&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/static analysis" rel="tag"&gt;static analysis&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-3219147843432424664?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/3219147843432424664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=3219147843432424664' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3219147843432424664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3219147843432424664'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/12/countperl-count-lines-packages-subs-and.html' title='countperl - count lines, packages, subs and complexity of Perl files'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-378418705827637694</id><published>2006-11-02T05:51:00.000-08:00</published><updated>2006-11-02T06:19:32.145-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='CPAN'/><category scheme='http://www.blogger.com/atom/ns#' term='DBI'/><title type='text'>Very Simple Wrapper for Perl DBI</title><content type='html'>I've released a new Perl module: &lt;b&gt;&lt;code&gt;DBIx::Wrapper::VerySimple&lt;/code&gt;&lt;/b&gt; which provides a very simple (object-oriented) wrapper around DBI.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;a href="http://search.cpan.org/dist/DBIx-Wrapper-VerySimple/"&gt;&lt;/a&gt;&lt;code&gt;DBIx::Wrapper::VerySimple&lt;/code&gt; provides three methods&lt;code style="font-style: italic;"&gt;&lt;/code&gt; &lt;code style="font-style: italic;"&gt;&lt;/code&gt; that between them cover about 98% of the SQL calls I've seen in Perl code over the years:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code style="font-style: italic;"&gt;fetch_all() -&lt;/code&gt; run a SQL statement (typically a SELECT statement) and get back an arrayref of hashrefs (one hashref for each result row.)&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;code style="font-style: italic;"&gt;fetch_hash() - &lt;/code&gt;run a SQL statement&lt;code&gt; &lt;/code&gt;(typically a SELECT statement) and get back a single hashref (for just one row.)&lt;code&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;code style="font-style: italic;"&gt;Do()&lt;/code&gt; - run a non-SELECT statement such as &lt;code&gt;CREATE or &lt;code&gt;DELETE.&lt;/code&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;code&gt;DBIx::Wrapper::VerySimple&lt;/code&gt; will use bind-variables if you pass them as additional arguments to &lt;code style="font-style: italic;"&gt;fetch_all()&lt;/code&gt;, &lt;code style="font-style: italic;"&gt;fetch_hash()&lt;/code&gt; or &lt;code style="font-style: italic;"&gt;Do()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;DBIx::Wrapper::VerySimple&lt;/code&gt; also provides a &lt;code style="font-style: italic;"&gt;get_args()&lt;/code&gt; method and a &lt;code style="font-style: italic;"&gt;dbh()&lt;/code&gt; method.  &lt;code style="font-style: italic;"&gt;get_args()&lt;/code&gt; returns the arguments originally passed to &lt;code&gt;new()&lt;/code&gt; so you can re-connect, etc. if need be. &lt;code style="font-style: italic;"&gt;dbh()&lt;/code&gt; returns the raw &lt;code&gt;DBI&lt;/code&gt; databse handle so you have ready access to all the features of &lt;code&gt;DBI&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;DBIx::Wrapper::VerySimple&lt;/code&gt; is available on the CPAN: &lt;a href="http://search.cpan.org/dist/DBIx-Wrapper-VerySimple/"&gt;http://search.cpan.org/dist/DBIx-Wrapper-VerySimple/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Technorati tags: &lt;a href="http://www.technorati.com/tag/CPAN"&gt;CPAN&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/DBI"&gt;DBI&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/Perl"&gt;Perl&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-378418705827637694?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/378418705827637694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=378418705827637694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/378418705827637694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/378418705827637694'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/11/very-simple-wrapper-for-perl-dbi.html' title='Very Simple Wrapper for Perl DBI'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-808971089595637877</id><published>2006-10-03T22:25:00.000-07:00</published><updated>2006-10-03T22:29:00.319-07:00</updated><title type='text'>Perl::Metrics::Simple</title><content type='html'>Counts files, packages, subroutines, and calculates &lt;a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;cyclomatic complexity&lt;/a&gt; of Perl files.&lt;br /&gt;&lt;br /&gt;I recently released an alpha version of new Perl module: &lt;a href="http://search.cpan.org/dist/Perl-Metrics-Simple/"&gt;Perl::Metrics::Simple&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There is an included script, in the &lt;span style="font-family:courier new;"&gt;examples/&lt;/span&gt; directory which produces output like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Perl Files:      $file_count&lt;br /&gt;&lt;br /&gt;Line Counts&lt;br /&gt;-----------&lt;br /&gt;lines:           $lines&lt;br /&gt;packages:        $package_count&lt;br /&gt;subs:            $sub_count&lt;br /&gt;all main code:   $main_stats-&gt;{lines}&lt;br /&gt;&lt;br /&gt;min. sub size:   $lines{min} lines&lt;br /&gt;max. sub size:   $lines{max} lines&lt;br /&gt;avg. sub size:   $lines{average} lines&lt;br /&gt;median sub size: $lines{median}&lt;br /&gt;&lt;br /&gt;McCabe Complexity&lt;br /&gt;-----------------&lt;br /&gt;min. main:    $main_complexity{min}&lt;br /&gt;max. main:    $main_complexity{max}&lt;br /&gt;median main:  $main_complexity{median}&lt;br /&gt;average main: $main_complexity{average}&lt;br /&gt;&lt;br /&gt;subs:&lt;br /&gt;min:             $complexity{min}&lt;br /&gt;max:             $complexity{max}&lt;br /&gt;avg:             $complexity{average}&lt;br /&gt;median:          $complexity{median}&lt;br /&gt;std. deviation:  $complexity{standard_deviation}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-808971089595637877?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/808971089595637877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=808971089595637877' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/808971089595637877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/808971089595637877'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/10/perlmetricssimple.html' title='Perl::Metrics::Simple'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-4513723280745134176</id><published>2006-09-22T07:28:00.000-07:00</published><updated>2006-09-22T07:38:56.533-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><title type='text'>Ruby plug-in for Eclipse</title><content type='html'>I recently found out there is a &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; plug-in for the &lt;a href="http://www.eclipse.org/"&gt;Eclipse IDE&lt;/a&gt;: The "Ruby Development Tool."&lt;br /&gt;&lt;br /&gt;Quick install instructions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Start up Eclipse.&lt;/li&gt;&lt;li&gt;Help &gt; Software Updates &gt; Find and Install...&lt;/li&gt;&lt;li&gt;Select "Search for new features to install"&lt;/li&gt;&lt;li&gt;Click "Next"&lt;/li&gt;&lt;li&gt;Click "New Remote Site..."&lt;/li&gt;&lt;li&gt;Enter the URL of stable release branch is: http://updatesite.rubypeople.org/release&lt;/li&gt;&lt;li&gt;Click "OK"&lt;/li&gt;&lt;li&gt;Click "Finish"&lt;/li&gt;&lt;/ol&gt;&lt;a href="http://rubyeclipse.sourceforge.net/index.rdt.html"&gt;Ruby Development Tool (RDT) web site: http://rubyeclipse.sourceforge.net/index.rdt.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www-128.ibm.com/developerworks/opensource/library/os-rubyeclipse/"&gt;Article on using RDT: http://www-128.ibm.com/developerworks/opensource/library/os-rubyeclipse/&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-4513723280745134176?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/4513723280745134176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=4513723280745134176' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4513723280745134176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/4513723280745134176'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/09/ruby-plug-in-for-eclipse.html' title='Ruby plug-in for Eclipse'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-3894052129854894841</id><published>2006-09-03T18:14:00.000-07:00</published><updated>2006-09-03T18:30:14.507-07:00</updated><title type='text'>Count Perl Code</title><content type='html'>I've started working on a module to analyze perl code report of files, lines, packages, subroutines, etc.&lt;br /&gt;&lt;br /&gt;A report could look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;% analyze.pl path/to/directory/of/perl/code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;files:     39&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;lines:     15929&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;packages:  39&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;subs:      336&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The module is (very tentively) named  &lt;span style="font-family:courier new;"&gt;Perl::Code::Analyze&lt;/span&gt;  and uses&lt;br /&gt;&lt;a href="http://search.cpan.org/dist/PPI/"&gt;Adam Kennedy's PPI module&lt;/a&gt; for the real work.&lt;br /&gt;&lt;br /&gt;A (very) alpha version of the module is at&lt;br /&gt; &lt;a href="http://g5-imac.matisse.net/%7Ematisse/Perl-Code-Analyze-0.01"&gt;http://g5-imac.matisse.net/~matisse/Perl-Code-Analyze-0.01&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's an example of a script that would use  &lt;span style="font-family:courier new;"&gt;Perl::Code::Analyze&lt;/span&gt;&lt;br /&gt;to produce the report shown above:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#!/usr/bin/perl&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;use strict;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;use warnings;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;use Perl::Code::Analyze;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $analzyer = Perl::Code::Analyze-&gt;new;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $analysis = $analzyer-&gt;analyze_files(@ARGV);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $file_count    = $analysis-&gt;file_count;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $package_count = $analysis-&gt;package_count;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $sub_count     = $analysis-&gt;sub_count;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;my $lines         = $analysis-&gt;lines;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;print &lt;&lt;"EOS";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;files:     $file_count&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;lines:     $lines&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;packages:  $package_count&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;subs:      $sub_count&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;EOS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;exit;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-3894052129854894841?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/3894052129854894841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=3894052129854894841' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3894052129854894841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/3894052129854894841'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/09/count-perl-code.html' title='Count Perl Code'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-8696355670071598976</id><published>2006-08-31T07:36:00.000-07:00</published><updated>2006-08-31T07:43:17.356-07:00</updated><title type='text'>Apple releases Launchd as Open Source</title><content type='html'>Apple has released their &lt;a href="http://launchd.macosforge.org/"&gt;launchd&lt;/a&gt; process manager under the &lt;a href="http://www.opensource.org/licenses/apache2.0.php"&gt;Apache Open Source License&lt;/a&gt; (version 2.0)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Launchd combines most of the features of the venerable Unix &lt;a href="http://en.wikipedia.org/wiki/Cron"&gt;cron&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Init"&gt;init&lt;/a&gt; facilities. You can use launchd to make sure a process is always running ("watchdogging"), to run jobs at specific times, to run jobs when/if a file appars in a specified directory, etc.&lt;br /&gt;&lt;br /&gt;I cover the basics of launchd in my book, "&lt;a href="http://www.matisse.net/OSX/"&gt;Unix for Mac OS X Tiger&lt;/a&gt;", and &lt;a href="http://arstechnica.com/reviews/os/macosx-10.4.ars/5"&gt;ars technicha covers it&lt;/a&gt; in their Tiger review.&lt;br /&gt;&lt;br /&gt;There is already a FreeBSD port of launchd.&lt;br /&gt;&lt;br /&gt;Macscripter.net has an &lt;a href="http://macscripter.net/articles/440_0_10_0_C/"&gt;article describing how to use launchd with AppleScript to access a Flashdrive&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-8696355670071598976?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/8696355670071598976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=8696355670071598976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8696355670071598976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/8696355670071598976'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/08/apple-releases-launchd-as-open-source.html' title='Apple releases Launchd as Open Source'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-2669060214312576574</id><published>2006-08-20T21:05:00.000-07:00</published><updated>2006-11-02T06:29:45.058-08:00</updated><title type='text'>Mock Classes in Perl Unit Tests</title><content type='html'>&lt;span style="color: rgb(204, 0, 0);font-size:85%;" &gt;&lt;span style="font-style: italic;"&gt;UPDATE:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;November 2, 2006:  &lt;/span&gt;&lt;a style="font-style: italic;" href="http://twoalpha.blogspot.com/2006/11/very-simple-wrapper-for-perl-dbi.html"&gt;I finally released the Wrapper module described here on the CPAN system&lt;/a&gt;&lt;span style="font-style: italic;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Today I added unit tests to a Perl module that uses the &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt; module. My module, &lt;span style="font-family:monospace;"&gt;&lt;a href="http://search.cpan.org/dist/DBIx-Wrapper-VerySimple/"&gt;DBIx::Wrapper::VerySimple&lt;/a&gt;&lt;/span&gt; is  one that I wrote years ago.&lt;br /&gt;&lt;br /&gt;The tests use three tiny mock classes that take the place of the real &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt; module. This allows the units tests to run in complete isolation from the actual &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt; module.&lt;br /&gt;&lt;br /&gt;Back when I wrote DBIx::Wrapper::VerySimple wasn't experienced enough to bother creating unit tests for my code. These days I create unit tests any time I create a new module for a project and sometimes for scripts as well.&lt;br /&gt;&lt;br /&gt;The challenge in this case was that constructor method, &lt;span style="font-style: italic; font-family: courier new;"&gt;DBIx::Wrapper::VerySimple-&gt;new()&lt;/span&gt; calls &lt;span style="font-family: courier new; font-style: italic;"&gt;DBI-&gt;connect()&lt;/span&gt;, and I didn't want my unit tests to require connecting to an actual database. My solution is to have three tiny mock classes in my test code including a DBI.pm that the tests load before DBI::Wrapper can load the real DBI.pm.&lt;br /&gt;&lt;br /&gt;Here's what my mock DBI.pm looks like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);font-family:monospace;" &gt;#  Mock class - for testing only&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;package&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; DBI;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;use&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; strict;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;use&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; warnings;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 0);font-family:monospace;" &gt;# warn 'Loading mock library ' . __FILE__;&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;my&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;MOCK_DBH_CLASS&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; = '&lt;/span&gt;&lt;span style="color: rgb(51, 0, 255);font-family:monospace;" &gt;DBI::Mock::dbh&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;';&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;my&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; %&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;ARGS&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; = ();&lt;br /&gt;&lt;br /&gt;sub connect {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;   my&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; ( $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;class&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;, @&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;args&lt;/span&gt; ) = @_;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;  my&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;fake_dbh&lt;/span&gt; = {};&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;   bless $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;fake_dbh&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;, $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;MOCK_DBH_CLASS&lt;/span&gt;;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;  $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;ARGS&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;{$&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;fake_dbh&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;} = \@&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;args&lt;/span&gt;;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;  return&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; $&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;fake_dbh&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;;&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;p face="monospace"&gt;1;&lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My test script loads the mock DBI.pm and two other mock classes before &lt;span style="font-family:monospace;"&gt;DBI::Wrapper&lt;/span&gt; is loaded for testing. This way, when &lt;span style="font-family:monospace;"&gt;DBI::Wrapper&lt;/span&gt; is compiled my mock &lt;span style="font-family:monospace;"&gt;DBI.pm&lt;/span&gt; is used instead of the real one:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(204, 0, 0);font-family:monospace;" &gt;# Ensure that DBI::Wrapper loads our mock DBI.pm&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;use&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; lib &lt;/span&gt;&lt;span style="color: rgb(51, 0, 255);font-family:monospace;" &gt;"$Bin/mock_lib"&lt;/span&gt;&lt;span style="font-family:monospace;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;use&lt;/span&gt; DBI;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;use&lt;/span&gt; DBI::Mock::dbh;&lt;span style="color: rgb(204, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;use&lt;/span&gt;&lt;span style="font-family:monospace;"&gt; DBI::Mock::sth;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This approaches works very well, and I was able to create unit tests that intercept all the calls that &lt;span style="font-family:monospace;"&gt;DBI::Wrapper&lt;/span&gt; makes that would normally go to the real &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt;, and my intercepting these I can check that &lt;span style="font-family:monospace;"&gt;DBI::Wrapper&lt;/span&gt; is passing the expected values to DBI. I am deliberately &lt;em&gt;not&lt;/em&gt; testing the real &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt; module which has its own extensive set of unit tests. I merely test that my module will make the expected calls to &lt;span style="font-family:monospace;"&gt;DBI&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;More about DBI::Wrapper&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The module is available online at &lt;a href="http://www.matisse.net/perl-modules/DBI/Wrapper/"&gt;http://www.matisse.net/perl-modules/DBI/Wrapper/&lt;/a&gt;&lt;br /&gt;The version with the new unit tests is version 0.04.&lt;br /&gt;&lt;br /&gt;From the README:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;p style="text-indent: 20pt;"&gt;&lt;span style="font-family:monospace;"&gt;DBI::Wrapper is a simple module that provides a high-level interface&lt;br /&gt;to the Perl DBI module. The provided methods are for fetching&lt;br /&gt;a single record (returns a hash-ref), many records (returns&lt;br /&gt;an array-ref of hash-refs), and for executing a non-select statement&lt;br /&gt;(returns a result code).&lt;br /&gt;&lt;br /&gt;The intention here is that your application will have much cleaner code,&lt;br /&gt;so instead of writing:&lt;br /&gt;&lt;br /&gt;$sql = 'SELECT name,address FROM $table WHERE zipcode=?';&lt;br /&gt;$sth = $dbh-&amp;gt;prepare($sql);&lt;br /&gt;$rv  = $sth-&amp;gt;execute($zipcode);&lt;br /&gt;@found_rows;&lt;br /&gt;while ( my $hash_ref = $sth-&amp;gt;fetchrow_hashref ) {&lt;br /&gt;push( @found_rows, $hash_ref );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;You would write:&lt;br /&gt;&lt;br /&gt;$sql = 'SELECT name,address FROM $table WHERE zipcode=?';&lt;br /&gt;$found_rows = $wrapper-&amp;gt;FetchAll($sql,$zipcode); # An array_ref of hash_refs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);font-family:monospace;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;I wrote the my version of DBI::Wrapper several years ago after I got the idea from a co-worker when I was doing a gig at TechTV.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-2669060214312576574?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/2669060214312576574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=2669060214312576574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/2669060214312576574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/2669060214312576574'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/08/mock-classes-in-perl-unit-tests.html' title='Mock Classes in Perl Unit Tests'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-115522250784236431</id><published>2006-08-10T08:03:00.000-07:00</published><updated>2006-08-10T08:08:28.030-07:00</updated><title type='text'>Compare BASIC, Ruby, Python, PHP, Perl, JavaScript, Lisp, False, Haskell etc.</title><content type='html'>&lt;a href="http://e-scribe.com/news/193" title="Comparing programming languages"&gt;Paul Bissex wrote three versions of a simple game, and posted it on E-Scribe news&lt;/a&gt;:  http://e-scribe.com/news/193&lt;br /&gt;Readers have contributes more versions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-115522250784236431?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/115522250784236431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=115522250784236431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/115522250784236431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/115522250784236431'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/08/compare-basic-ruby-python-php-perl.html' title='Compare BASIC, Ruby, Python, PHP, Perl, JavaScript, Lisp, False, Haskell etc.'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114925645212643821</id><published>2006-06-02T06:50:00.000-07:00</published><updated>2006-06-02T06:54:12.193-07:00</updated><title type='text'>Comparing Pair Programming to Solo Programming</title><content type='html'>Brian Slesinsky wrote recently &lt;a href="http://slesinsky.org/brian/code/pair_versus_review.html" title="prefers pair programming to code reviews"&gt;comparing Pair Programming to Code Reviews&lt;/a&gt; and argues that Pair Programming is better. I agree with his reasoning. I also think we need more hard-data on comparison of pairing vs. solo programming. It is a multi-dimensional issue, involving at least:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Total developer time spent.&lt;/li&gt;&lt;li&gt;Code quality and increase/reduction in the cost of product quality (more bugs == higher cost.)&lt;/li&gt;&lt;li&gt;Time-to-market.  Two people spending 70 hours in parallel is faster to market than one person spending 100 hours.&lt;/li&gt;&lt;li&gt;Personalities and social dynamics. People have widely differing and strong held feelings about pairing vs. solo programming.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/extreme programming" rel="tag"&gt;extreme programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/pair programming" rel="tag"&gt;pair programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/code review" rel="tag"&gt;code review&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/XP" rel="tag"&gt;XP&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114925645212643821?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114925645212643821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114925645212643821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114925645212643821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114925645212643821'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/06/comparing-pair-programming-to-solo.html' title='Comparing Pair Programming to Solo Programming'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114917618344696877</id><published>2006-06-01T08:33:00.000-07:00</published><updated>2006-06-01T08:37:03.206-07:00</updated><title type='text'>How much eXtremism is too extreme?</title><content type='html'>Blain Buxton recently wrote about &lt;a href="http://blog.blainebuxton.com/2006/05/pair-programming-is-all-time-too-much.html" title="always pairing can be bad"&gt;how Pair Programming all the time could be bad&lt;/a&gt;, and in general makes the case for not being extreme about being eXtreme.&lt;br /&gt;&lt;br /&gt;I think the most important point Blaine makes is that one should always be focused on what is best for the process, not on adhering to any particular technique.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/extreme programming" rel="tag"&gt;extreme programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/pair programming" rel="tag"&gt;pair programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/XP" rel="tag"&gt;XP&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114917618344696877?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114917618344696877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114917618344696877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114917618344696877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114917618344696877'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/06/how-much-extremism-is-too-extreme.html' title='How much eXtremism is too extreme?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114909386037795867</id><published>2006-05-31T08:34:00.000-07:00</published><updated>2006-05-31T09:44:20.426-07:00</updated><title type='text'>Pair-Programming Experiment at Stanford University</title><content type='html'>Stanford University is in the middle of a formal experiment on &lt;a href="http://www.pittsburghcorning.com/builders/newproducts_thickset.asp" title="http://en.wikipedia.org/wiki/Pair_Programming"&gt;Pair Programming&lt;/a&gt;. I participated in the experiment this past weekend and had a lot of fun and, hopefully, helped advanced the state of knowledge about this controversial software development technique.&lt;br /&gt;&lt;br /&gt;A PDF document describing the experiment is available at &lt;a href="http://hci.stanford.edu/research/pairs/PairProgramming-WhenWhy.pdf" title="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;http://hci.stanford.edu/research/pairs/PairProgramming-WhenWhy.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The experiment is currently in the second ("Laboratory Experiment") phase as described in that document.&lt;br /&gt;In the first phase ("Ethnographic Field Study") of the experiment the researchers visited two companies where pair-programming is regularly practiced and observed and recorded audio of programming pairs. These observations helped the researchers develop some hypothesis which may be checked by further work in the experiment.&lt;br /&gt;&lt;br /&gt;The researchers are focusing on the interaction between the people in the pairs (the "socio-cognitive factors" is how they say it.) The current phase of the experiment involves controlled tests where a pair of programmers or a solo programmer complete a warmup task and then a larger task (which takes around 5-6 hours all together.) The programmers are recorded via audio, video, and screen captures.&lt;br /&gt;&lt;br /&gt;During my pairing session this past weekend we talked a bit about the notion that once we humans have a goal we often have a strong impulse to start acting towards that goal, without necessarily doing much planning or testing - like driving nails before deciding where, exactly to drive the nails, and that we continue with our actions without doing much checking if we are in fact heading towards our goal. I don't think that Pair Programming stops individuals from having this impulse, but the presence of a second person makes it more likely, perhaps, that someone else will stop us. Hence my new joking slogan: "&lt;strong&gt;Pair Programming: It's not twice as smart, it's half as dumb!&lt;/strong&gt;"&lt;br /&gt;&lt;br /&gt;Pair Programming as a formally recognized technique has been around for over a decade now, and as an informal reality I would guess it has been around for as long as there has programming. There has been only a little formal study of Pair Programming though, and Pair Programming is perhaps the most controversial technique in the &lt;a href="http://en.wikipedia.org/wiki/Pair_Programming" title="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;eXtreme Programming&lt;/a&gt; methodology, touching as it does directly on people's self-image and personalities.&lt;br /&gt;&lt;br /&gt;I hope this experiment will help advance the state of knowledge about software development in general, and Pair Programming in particular, so that we can make better decisions about how to build things.&lt;br /&gt;&lt;br /&gt;The experiment is led by Robert P. Plummer, PhD., a Lecturer in the Stanford Department of Computer Science. Inquiries about the experiment can be sent to &lt;strong&gt;experiment at cs.stanford.edu&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/agile" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/extreme programming" rel="tag"&gt;extreme programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/pair programming" rel="tag"&gt;pair programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114909386037795867?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114909386037795867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114909386037795867' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114909386037795867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114909386037795867'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/05/pair-programming-experiment-at.html' title='Pair-Programming Experiment at Stanford University'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114908858689876724</id><published>2006-05-31T08:13:00.000-07:00</published><updated>2006-05-31T08:16:26.970-07:00</updated><title type='text'>Test-Driven Development in the Physical World</title><content type='html'>It's occurred to me that we routinely practice Test Driven Development in the physical world, such as building houses.&lt;br /&gt;&lt;br /&gt;Consider how we use a "test first" approach in construction:&lt;br /&gt;&lt;br /&gt;Typically, if you want a hole in the wall 30 inches below the ceiling:&lt;br /&gt; 1. You take a ruler and make a mark on the wall 30" below the ceiling.&lt;br /&gt; 2. You drill a hole where the mark is.&lt;br /&gt; 3. If your hole is where the mark is/was, your test passes, otherwise, go to step 1.&lt;br /&gt;&lt;br /&gt;Now consider what that would be like without doing it "test first":&lt;br /&gt;&lt;br /&gt; 1. You drill a hole in the wall.&lt;br /&gt; 2. You measure hole far from the ceiling the hole is.&lt;br /&gt; 3. If the hole is 30" from the ceiling, you win . Otherwise, go to step 1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114908858689876724?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114908858689876724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114908858689876724' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114908858689876724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114908858689876724'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/05/test-driven-development-in-physical.html' title='Test-Driven Development in the Physical World'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114853512182830100</id><published>2006-05-24T22:28:00.000-07:00</published><updated>2006-05-24T22:36:06.583-07:00</updated><title type='text'>Software Best Practices Wiki?</title><content type='html'>&lt;span style="font-size:14pt;"&gt;I've been thinking about creating a&lt;/span&gt; &lt;span style="font-size:14pt;"&gt;&lt;a href="http://localhost:8080/WikiWikiWeb"&gt;wiki&lt;/a&gt;&lt;/span&gt; &lt;span style="font-size:14pt;"&gt;for software development "best practices."&lt;br /&gt;Something that might contain entries like this:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:14pt;"&gt;&lt;strong&gt;&lt;br /&gt;1. Where Applications Save Data&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-size:14pt;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;Many applications need to save data between invocations of the application.&lt;/div&gt;&lt;div&gt;Some examples are:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;User Preferences.&lt;/li&gt;&lt;li&gt;Documents or other work product from the application (web pages, spreadsheet, reports, images, etc.)&lt;/li&gt;&lt;li&gt;Cache files.&lt;/li&gt;&lt;li&gt;Other long-lived data (bookeeping data, emails, audit trails, etc.)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-size:13pt;"&gt;&lt;strong&gt;&lt;br /&gt;1.1. Forces at Work&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-size:13pt;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Some of the forces at work in determing where an application should save data include:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Access ability: the application needs write and read access.&lt;/li&gt;&lt;li&gt;Upgradeability: some data must survive a software upgrade.&lt;/li&gt;&lt;li&gt;Multiple users: some applications are used by many users.&lt;/li&gt;&lt;li&gt;Privacy and security: Some data must be protected from unauthorized access.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The types of data an application saves are:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Temporary vs. Long-Lived&lt;/li&gt;&lt;li&gt;User-associated vs. Application-associated&lt;/li&gt;&lt;li&gt;Internal use by the application vs. Suitable for distribution outside the application environment.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:13pt;"&gt;&lt;strong&gt;1.2. General Principles&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;Application shall:&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;Save Long-Lived data where it will survive an upgrade.&lt;/li&gt;&lt;li&gt;Save Temporary data where it is easily garbage-collected.&lt;/li&gt;&lt;li&gt;Save per-user data in a place belonging to the user.&lt;/li&gt;&lt;li&gt;Save data for distribution in a place the user is explicitly informed about.&lt;/li&gt;&lt;li&gt;Use encryption to help secure privacy.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114853512182830100?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114853512182830100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114853512182830100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114853512182830100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114853512182830100'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/05/software-best-practices-wiki.html' title='Software Best Practices Wiki?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114771326584411644</id><published>2006-05-15T10:11:00.000-07:00</published><updated>2006-05-15T10:14:25.910-07:00</updated><title type='text'>Wiki's in the Workplace</title><content type='html'>Peter Thoeny and Dan Woods, co-authors of a &lt;a href="http://twiki.org/cgi-bin/view/Codev/WikisInTheWorkplaceBook" title="Wiki page about the book"&gt;Book on Wikis in the Workplace&lt;/a&gt; have started a company to help business use Wikis: &lt;a href="http://www.structuredwikis.com/" title="Web site for Structurted Wikis, LLC"&gt;StructuredWikis: http://www.structuredwikis.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've seen wiki engines used at three very different organizations: The Burning Man tech-team, Technorati.com, and Barclays Global Investors. I think wikis have a important role to play in almost all modern businesses that have an Intranet of any kind.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/intranet" rel="tag"&gt;intranet&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/wiki" rel="tag"&gt;wiki&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114771326584411644?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114771326584411644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114771326584411644' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114771326584411644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114771326584411644'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/05/wikis-in-workplace.html' title='Wiki&apos;s in the Workplace'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114753599729898024</id><published>2006-05-13T08:57:00.000-07:00</published><updated>2006-05-13T08:59:57.300-07:00</updated><title type='text'>Trackback Explained</title><content type='html'>Suzanne Stefanac explains trackbacks: &lt;a href="http://www.dispatchesfromblogistan.com/trackback-demystified/" title="blog posting"&gt;http://www.dispatchesfromblogistan.com/trackback-demystified&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/trackback" rel="tag"&gt;trackback&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/blogging" rel="tag"&gt;blogging&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114753599729898024?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114753599729898024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114753599729898024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114753599729898024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114753599729898024'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/05/trackback-explained_13.html' title='Trackback Explained'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114585602879753775</id><published>2006-04-24T06:59:00.000-07:00</published><updated>2006-04-24T07:01:59.153-07:00</updated><title type='text'>Ruby / Flash Gateway: Alph</title><content type='html'>I saw a cool demo yesterday of &lt;a href="http://rubyforge.org/projects/alph/" title="Alph SourceForge project."&gt;Alph&lt;/a&gt;. Alph allows you to use &lt;a href="http://rubycentral.org/" title="Ruby Central"&gt;Ruby&lt;/a&gt; to control a Flash movie.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/flash" rel="tag"&gt;flash&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/ruby" rel="tag"&gt;ruby&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114585602879753775?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114585602879753775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114585602879753775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114585602879753775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114585602879753775'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/ruby-flash-gateway-alph_24.html' title='Ruby / Flash Gateway: Alph'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114505363490806827</id><published>2006-04-14T15:25:00.000-07:00</published><updated>2006-04-15T10:12:35.660-07:00</updated><title type='text'>The WELL is Down!</title><content type='html'>My long-time online home, The Whole Earth 'Lectronic Link has been unavailable for several hours now - the longest unplanned outage I can recall in over 10 years.&lt;br /&gt;&lt;br /&gt;I no longer have any staff member phone numbers but I called their office and spoke with Gail Williams, Director of Community and she pointed me to &lt;a href="http://www.salon.com/wellstatus/"&gt;http://www.salon.com/wellstatus/&lt;/a&gt; - where recent status info should be available. She also told me that people have sent flowers and left goodwill messages ("beams") on the WELL's voice mail.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update: Looks like the WELL's command-line interface came back up just before midnight April 14th, Pacific Time.&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114505363490806827?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114505363490806827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114505363490806827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114505363490806827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114505363490806827'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/well-is-down.html' title='The WELL is Down!'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114477096785879194</id><published>2006-04-11T08:54:00.000-07:00</published><updated>2006-04-11T08:56:07.913-07:00</updated><title type='text'>Wanted: Blogging Platform with Revision History</title><content type='html'>I'd love to have a blogging platform  that supports a Revision History of Published Posts:&lt;br /&gt;&lt;br /&gt;Desired features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Each published version of a posting would be saved.&lt;/li&gt;&lt;li&gt;Readers would be able to see a list of versions.&lt;/li&gt;&lt;li&gt;Reader can choose to view a specific version.&lt;/li&gt;&lt;li&gt;Reader may compare any two versions.&lt;/li&gt;&lt;/ul&gt;I'm imagining that each posting would be stored under some kind of &lt;a href="http://www.google.com/url?sa=t&amp;amp;amp;amp;amp;ct=res&amp;amp;amp;amp;amp;cd=1&amp;amp;amp;amp;amp;url=http%3A//en.wikipedia.org/wiki/Revision_control&amp;amp;amp;amp;amp;ei=e9A7RMGQCqmCYbO2oL8H&amp;amp;amp;amp;amp;sig2=zihSw1KCAi3-Kt5HLuGkgQ" target="_blank" title="Wikipedia entry on Revision Control: Revision control (also known as version control) is the management of multiple revisions of the same unit of information. It is most commonly used in engineering and software development to manage ongoing evolution of digital documents like application source code, art resources such as blueprints or electronic models and other critical information that may be worked on by a team of people...' (click for more)"&gt;Revision Control&lt;/a&gt; system, similar to how wiki's treat pages.&lt;br /&gt;&lt;br /&gt;I'd be glad to help make this happen.&lt;br /&gt;&lt;br /&gt;I've posted this in the &lt;a href="http://groups.google.com/group/bloggerDev/browse_frm/thread/4c30c9d06bebdac6/#" target="_blank" title="Posting in BloggerDev Group"&gt;BloggerDev&lt;/a&gt; group - if you are reading this and agree, please go there and post a "me too" comment.&lt;br /&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/blogging" rel="tag"&gt;blogging&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/revision control" rel="tag"&gt;revision control&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114477096785879194?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114477096785879194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114477096785879194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114477096785879194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114477096785879194'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/wanted-blogging-platform-with-revision.html' title='Wanted: Blogging Platform with Revision History'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114463928458644736</id><published>2006-04-09T20:20:00.000-07:00</published><updated>2006-12-13T08:42:02.384-08:00</updated><title type='text'>Making Things is a Fractal Process</title><content type='html'>&lt;pre&gt;/*&lt;br /&gt;* All building and making of things involves a fractal (recursive) process&lt;br /&gt;* like this pseudo-code:&lt;br /&gt;* Takes a set of Requirements and returns something new&lt;br /&gt;*/&lt;br /&gt;public Thing &lt;span style="color:#ff00ff;"&gt;makeNewThing&lt;/span&gt; ( Requirements &lt;span style="color:#0000ff;"&gt;requirements&lt;/span&gt; ) {&lt;br /&gt;    Thing &lt;span style="color:#0000ff;"&gt;newThing&lt;/span&gt; = ();&lt;br /&gt;    while ( &lt;span style="color:#0000ff;"&gt;requirements&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;not_satisfied&lt;/span&gt; ) {&lt;br /&gt;        Things &lt;span style="color:#0000ff;"&gt;requiredPieces&lt;/span&gt; = &lt;span style="color:#0000ff;"&gt;requirements&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;whatCanWeMakeOneFrom&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;;&lt;/span&gt;&lt;br /&gt;        Things &lt;span style="color:#0000ff;"&gt;piecesWeHave&lt;/span&gt;   =&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;whatDoWeHaveAlready&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;requirements&lt;/span&gt;,&lt;span style="color:#0000ff;"&gt;requiredPieces&lt;/span&gt;);&lt;br /&gt;        Things &lt;span style="color:#0000ff;"&gt;piecesNeeded&lt;/span&gt;   =&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;requiredPieces&lt;/span&gt; - &lt;span style="color:#0000ff;"&gt;piecesWehave&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;        newThing&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;assemblePieces&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;piecesWeHave&lt;/span&gt;);&lt;br /&gt;        foreach Thing &lt;span style="color:#0000ff;"&gt;neededPiece&lt;/span&gt; ( &lt;span style="color:#0000ff;"&gt;piecesNeeded&lt;/span&gt; ) {&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;            piecesWeHave&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;add&lt;/span&gt;( makeSomething(&lt;span style="color:#0000ff;"&gt;neededPiece&lt;/span&gt;) );&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;            newThing&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;assemblePieces&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;piecesWeHave&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;        requirements&lt;/span&gt;.&lt;span style="color:#ff00ff;"&gt;check&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;newThing&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    return &lt;span style="color:#0000ff;"&gt;newThing&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/construction" rel="tag"&gt;construction&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114463928458644736?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114463928458644736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114463928458644736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114463928458644736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114463928458644736'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/making-things-is-fractal-process.html' title='Making Things is a Fractal Process'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114462823281906202</id><published>2006-04-09T17:18:00.000-07:00</published><updated>2006-06-05T07:57:42.060-07:00</updated><title type='text'>Run Windows, Mac OS X, Solaris, and Linux Simultaneously</title><content type='html'>See: Parallels Workstation: &lt;a href="http://www.parallels.com/en/products/workstation/" title="Product description"&gt;http://www.parallels.com/en/products/workstation/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The folks at Parallels, Inc. have made a real breakthrough - building upon Intel's &lt;a href="http://en.wikipedia.org/wiki/Virtualization_Technology"&gt;virtualization&lt;/a&gt; feature of their newest CPUs, Parallels allows you to boot into one operating system, and then run one &lt;em&gt;or more&lt;/em&gt; others as "hosted" operating system in windows in the primary one.&lt;br /&gt;&lt;br /&gt;In other words: You boot into say, Mac OS X, and then run a real copy of Windows XP, in a window. The hosted OS is &lt;em&gt;not&lt;/em&gt; running on a chip emulator - each OS is running as a virtual machine.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://www.parallels.com/en/products/workstation/screenshots/sc201/" target="_blank" title="XP on a Mac"&gt;Windows XP "guest" on Mac OS X "primary"&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://www.parallels.com/en/products/workstation/screenshots/sc204/" target="_blank" title="Windows 3.11 and Solaris on Mac OS X"&gt;Windows 3.11, Solaris 10.0 on top of Mac OS&lt;/a&gt;&lt;br /&gt;See also:&lt;/li&gt;&lt;li&gt; jtl's posting: &lt;a href="http://www.jtl.us/mt-main/archives/000602.html"&gt;http://www.jtl.us/mt-main/archives/000602.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://parallelsvirtualization.blogspot.com/" title="parallels blog"&gt;The official Parallels Blog&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.paulstamatiou.com/2006/04/23/triple-boot-your-intel-mac/"&gt;Paul Stamatiou's blog&lt;/a&gt; has a discussion comparing Parallels to &lt;a href="http://www.apple.com/macosx/bootcamp/" title="Apple's Bootcamp page"&gt;Bootcamp&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/Mac OS X" rel="tag"&gt;Mac OS X&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/virtualization" rel="tag"&gt;virtualization&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/Windows" rel="tag"&gt;Windows&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114462823281906202?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114462823281906202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114462823281906202' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114462823281906202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114462823281906202'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/run-windows-mac-os-x-solaris-and-linux.html' title='Run Windows, Mac OS X, Solaris, and Linux Simultaneously'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114269984900274417</id><published>2006-04-09T10:39:00.000-07:00</published><updated>2007-01-02T01:12:31.466-08:00</updated><title type='text'>Software Development is like Building Construction</title><content type='html'>&lt;div&gt;The process of Software Development is a lot like the process of Building Construction, and although they also have important differences, these differences are mainly differences of degree rather than kind.&lt;br /&gt;&lt;br /&gt;Software folks occasionally make a big deal of the differences between software development and building construction, and building trades/architecture folks often think you cannot do iterative design on buildings.&lt;br /&gt;&lt;br /&gt;The fact is, software development and building construction have many important similarities, and many processes that are effective in both.&lt;br /&gt;&lt;br /&gt;Both software development and building construction involves the marshaling of numerous interdependent systems designed, built, and assembled by a variety of highly specialized people.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Dependencies&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;In the software world we have architecture issues (client/server, message-passing, batch processing, micro-kernel, etc.) data structures (databases), business logic, graphic and other user-interface design, etc.&lt;br /&gt;&lt;br /&gt;In the world of buildings we have architecture, foundation, frame or shell, electrical, plumbing, wall coverings, HVAC, etc.&lt;br /&gt;&lt;br /&gt;Both software development and building construction have numerous layers of dependencies. There are many variations on the actual stack of what depends upon what, but there are always dependencies.&lt;br /&gt;&lt;br /&gt;Typical examples of the stack of dependencies in software are hardware, then the operating system, then the programming language, then some kind of data structure, then something to manipulate the data, etc. Buildings too have their stack of dependencies: connection to the Earth (foundation), the load-bearing frame or envelope, utilities, skin/weather-proofing, etc.&lt;br /&gt;&lt;br /&gt;Some might say that software may be "built" in many different ways, but that buildings must be built from the ground up. Well, if you think buildings &lt;em&gt;must&lt;/em&gt; be built ground-up, do a search for "&lt;a href="http://www.google.com/search?q=%22Linn+Cove+Viaduct%22"&gt;Linn Cove Viaduct&lt;/a&gt;" and see &lt;a href="http://www.dot.state.oh.us/se/SI9/19Freeby.pdf"&gt;http://www.dot.state.oh.us/se/SI9/19Freeby.pdf&lt;/a&gt;, and consider how a space station can be built in orbit.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Incremental Design&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;These days (early 21st Century) the concept of incremental design is reasonably well known in the software world, and is arguably becoming more popular. There is a long history of incremental design in building - think of the Wright brothers many iterations on their aircraft design and their invention of and use of wind tunnels to test and refine (shall we say "refactor"?) their designs.&lt;br /&gt;&lt;br /&gt;Both mathematical and &lt;a href="http://www.metmuseum.org/toah/ho/05/eac/hob_1984.397.htm"&gt;physical models&lt;/a&gt; have been in the repertoire of the making process for thousands of years.&lt;br /&gt;&lt;br /&gt;These days (2006) we in the software world try to use intensive tests (such as unit tests) and clever modeling in our design/development processes.&lt;br /&gt;&lt;br /&gt;Almost 20 years ago I was building full-scale mockups, tests, and experiments of buildings &lt;em&gt;as part of the design process&lt;/em&gt; and it works. I was working with Chris Alexander's Center for Environmental Structure and among many other examples of iterative design, complete with unit tests was the work we did on the exterior walls of the Julian Street Homeless Shelter in San Jose ( see this &lt;a href="http://www.katarxis3.com/Gallery/publicbuildings/new-polaroid-tweaked.jpg"&gt;exterior photo of the main building&lt;/a&gt;, and this &lt;a href="http://www.katarxis3.com/Gallery/publicbuildings/sjdininghall.jpg"&gt;interior of the dining hall&lt;/a&gt; - those are sprayed-concrete trusses, also the results of a test-driven design process.)&lt;br /&gt;&lt;br /&gt;The exterior wall system went through many iterations, and there were many kinds of tests, of both the visual and physical composition. In each test we would establish a certain standard or required result - sort of making an assertion about the design or structure, and then make a change or build something to implement the assertion.&lt;br /&gt;&lt;br /&gt;Some of the tests were physical such as "Is the cover glaze sufficiently free of cracks?" Probably the most frequent kind of tests were tests to verify that a particular feature or system maintained or improved the life in the overall structure. For example, such a test might be "Check that the way the tiles are embedded creates a tangible border that increases the life of the whole wall." And then we would embed tiles using one or another method and check, if the test passed.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The design and development of software and the design and development of the built environment, like all building processes are iterative processes that involve the repeated assembly of existing materials in new combinations and structures, informed by human creativity and driven by human needs and desires. Humans have been building physical structures for many thousands of years, and some techniques have remained essential unchanged in all that time, while other techniques and materials have come into existence more, or less, recently. Those who build - builders of any kind - would do well to learn from each other as builders, and learn to search for the commonalities in our processes, successes, and failures, and to recognize objectively the differences, which are fewer than is commonly believed.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://search.cpan.org/%7Ethaljef/"&gt;Jeff Thalhammer&lt;/a&gt; for 'code review' on this document.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;See Also&lt;/strong&gt;&lt;/span&gt;&lt;span style="text-decoration:underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.katarxis3.com/Review_Nature_Order.htm" title="Review of The Nature of Order"&gt;Review of Christopher Alexander's "The Nature of Order"&lt;/a&gt;, in Katarxis N&amp;#186; 3&lt;/li&gt;&lt;li&gt;A contrary opinion: &lt;a href="http://www.agilemanagement.net/Articles/Weblog/ConstructionAnalogyAgain.html"&gt;http://www.agilemanagement.net/Articles/Weblog/ConstructionAnalogyAgain.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Another contrary opinion: &lt;a href="http://www.jamesshore.com/Blog/That-Damned-Construction-Analogy.html" title="James Shore's blog."&gt;http://www.jamesshore.com/Blog/That-Damned-Construction-Analogy.html&lt;/a&gt; in which James Shore argues that "&lt;em&gt;Ultimately, construction is about dealing with physical objects.&lt;/em&gt;", which I disagree with: In my view, ultimately construction is about making things. I suspect that Mr. Shore has never built a building.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0140139966/qid=948861466/sr=1-1/103-4910299-4269441" title="How Buildings Learn - at Amazon.com"&gt;How Buildings Learn: What Happens After They're Built&lt;/a&gt; (Viking-Penguin, 1994; &lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0753800500/qid=948913890/sr=1-2/026-2691386-4723249" title="How Buildings Learn - at Amazon.co.uk"&gt;in the UK, Orion Books&lt;/a&gt;). The author, &lt;a href="http://www.well.com/~sbb/" title="Stewart Brand's Home Page"&gt;Stewart Brand&lt;/a&gt; says "&lt;em&gt;It was written (and designed and laid out in detail) to change the practice of building and the use of buildings the way Chris Alexander's A Pattern Language and Jane Jacobs's The Death and Life of Great American Cities have done.&lt;/em&gt;"&lt;/li&gt;&lt;li&gt;Martin Fowler's &lt;a href="http://www.refactoring.com/" title="refactoring.com"&gt;Refactoring Home Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Here's another disagreeing post - this one from &lt;a href="http://www.jrothman.com/weblog/2006/04/construction-metaphor-doesnt-work-for.html" title="Johanna's opinion"&gt;Johanna Rothman&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.gdinwiddie.com/2006/12/27/the-construction-analogy/"&gt;George Dinwiddie ponders this issue&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/buildings" rel="tag"&gt;buildings&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/construction" rel="tag"&gt;construction&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software" rel="tag"&gt;software&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/software development" rel="tag"&gt;software development&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114269984900274417?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114269984900274417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114269984900274417' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114269984900274417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114269984900274417'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/software-development-is-like-building.html' title='Software Development is like Building Construction'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114343387686365584</id><published>2006-04-08T13:58:00.000-07:00</published><updated>2009-06-09T07:59:37.100-07:00</updated><title type='text'>The WELL Gopher</title><content type='html'>&lt;span style="color:#006738;"&gt;UPDATE - (June 2009) The WELL's Gopher server was decommissioned some months back, but the content is still available via a web server at: &lt;/span&gt;&lt;a href="http://www.well.com/gopher/" title="Web server with content from the WELL Gopher"&gt;http://www.well.com/gopher/&lt;/a&gt;&lt;span style="color:#006738;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/The_WELL" title="Wikipedia entry for The WELL"&gt;The WELL&lt;/a&gt; is an online discussion system that started in 1985. At the very end of 1991, in fact, on New Years' Eve, The WELL connected to the Internet (via 56K connection to &lt;a href="http://#here" title="Bay Area Regional Research Network"&gt;BARRNet&lt;/a&gt;, router configuration by &lt;a href="http://www.clock.org/~fair/" title="Erik E. Fair's page at clock.org"&gt;Erik Fair&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;In those days I was the Customer Support Manager at The WELL and I wanted us to give something back to the Internet community. In those days "anonymous FTP" sites were a common way for organizations to share information with the public over the Internet. I suggested that The WELL create an anonymous FTP site where we would provide access to interesting information, drawing heavily on our association with &lt;a href="http://en.wikipedia.org/wiki/Whole_Earth_Catalog" title="Wikipedia entry for Whole Earth Catalog"&gt;The Whole Earth Catalog&lt;/a&gt; (The WELL was half owned by The POINT Foundation, publisher of The Whole Earth Catalog, and we were in the same building with the catalog staff.)&lt;br /&gt;&lt;br /&gt;I recruited a small group of volunteer WELL users to be the editorial staff of the new site: &lt;a href="http://www.well.com/~jerod23/" title="Jerod's home page"&gt;Jerod Pore&lt;/a&gt;, &lt;a href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A//www.ericstheise.com/&amp;amp;ei=Kx04RNyvEZT0YMSksbgH&amp;amp;sig2=F9yrUNqaxXXBguMzDjM9Og" title="Eric's  Web Site"&gt;Eric S. Theise&lt;/a&gt;, &lt;a href="http://www.weblogsky.com/" title="Weblogsky"&gt;Jon Lebkowsky&lt;/a&gt;, and &lt;a href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A//weblog.bluepenguin.us/&amp;amp;ei=Sh04RLHxHMqWYNGArdwH&amp;amp;sig2=BV5oJM2qa_NvXlQvWVtoGw" title="Paul's blog"&gt;Paul Holbrook&lt;/a&gt;, and we started discussing what should be in the new site. During this (online) discussion a WELL user who was very involved with the Internet, &lt;a href="http://vielmetti.typepad.com/" title="Ed Vielmetti's blog - Vacuum"&gt;Ed Vielmetti,&lt;/a&gt; suggested we check out this cool new rodent-based technology developed at the University of &lt;span style="text-decoration:line-through;"&gt;Michigan&lt;/span&gt;  Minnesota (the "Golden Gophers"). This new thing was called "&lt;a href="http://matisse.net/files/glossary#Gopher" title="Glossary entry"&gt;gopher&lt;/a&gt;", and I immediately saw that it was much easier to use than FTP.&lt;br /&gt;&lt;br /&gt;Eric Theise and I had a bit of a fight over that - Eric felt that FTP was the widely used and well known standard and we'd be cutting out all the people who didn't yet have access to a gopher client. I was all steve-jobsian about it "the interface is so much better, people will get a gopher client, this is the future, blah blah blah". I think it was the one place where I strongly asserted my WELL-staff role. We went with gopher.&lt;br /&gt;&lt;br /&gt;The content in The WELL Gopher was a direct outgrowth of the WELL's connection to &lt;a href="http://en.wikipedia.org/wiki/Whole_Earth_Review" title="Wikipedia entry for Whole Earth Review"&gt;The Whole Earth Review&lt;/a&gt; - part of my evil plan was to bring the editorial approach of WER to cyberspace - in fact the top-level categories in the gopher were originally taken directly from the categories that the Whole Earth Catalog used.&lt;br /&gt;&lt;br /&gt;There was a point when the WELL gopher and the spies.com gopher were the two hottest places in gopherspace.  This all came down to three really important factors:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: We had great editors like Jon, Jerod, Eric and Paul choosing great stuff. See this great story, "&lt;a href="gopher://gopher.well.com/00/WER/forces.adrift" title="Plain text version"&gt;Forces Adrift, a Tale of Our Forces Afloat&lt;/a&gt;", by Chuck Charlton.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: We were choosing from a pool of ideas that mapped very well onto the population using cyberspace. Roger Karraker's "&lt;a href="gopher://gopher.well.com/00/Communications/Highways_of_the_Mind.txt" title="Plain text version"&gt;Highways of the Mind&lt;/a&gt;" article is still relevent.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: We had exclusive content - no offsite links for the first year or so. With maybe a couple exceptions the WELL gopher was the exclusive online location of all the content. This made us editors think more, and choose less.&lt;/li&gt;&lt;/ol&gt;These days there are many things like the WELL gopher, and nothing like it - like a magazibne with a particular editorial group, the result is really all about the people and historical circumstances at the times of creation.&lt;br /&gt;&lt;br /&gt;Notes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Gopherspace is part of webspace. "The web", at least circa 1993 was all the resources reachable via (at least) the &lt;a href="http://matisse.net/files/glossary#FTP" title="Glossary entry"&gt;FTP&lt;/a&gt;, &lt;a href="http://matisse.net/files/glossary#Gopher" title="Glossary entry"&gt;gopher&lt;/a&gt;, and &lt;a href="http://matisse.net/files/glossary#HTTP" title="Glossary entry"&gt;HTTP&lt;/a&gt; protocols. You could throw in &lt;a href="http://matisse.net/files/glossary#WAIS" title="Glossary entry"&gt;WAIS&lt;/a&gt;, &lt;a href="http://matisse.net/files/glossary#Telnet" title="Glossary entry"&gt;telnet&lt;/a&gt; and maybe a couple of others.&lt;/li&gt;&lt;li&gt;The WELL gopher did (and does) utilize a server that responds to both the gopher and HTTP protocols, so you can reach it with the URL &lt;span style="text-decoration:underline;"&gt;gopher://gopher.well.com/&lt;/span&gt; or &lt;span style="text-decoration:underline;"&gt;http://gopher.well.com:70/&lt;/span&gt; Initially the server only handled the gopher protocol but was soon switched to the &lt;a href="http://osx.freshmeat.net/projects/gn/" title="GN Server page at Freshmeat"&gt;GN server&lt;/a&gt; which handles both protocols, so even if you mistakenly think that a web site must utilize HTTP, the WELL gopher still qualifies.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/gopher" rel="tag"&gt;gopher&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/history" rel="tag"&gt;history&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114343387686365584?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114343387686365584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114343387686365584' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114343387686365584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114343387686365584'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/well-gopher.html' title='The WELL Gopher'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114394961394050891</id><published>2006-04-01T19:42:00.000-08:00</published><updated>2006-04-01T19:46:54.113-08:00</updated><title type='text'>The WELL Turns 21</title><content type='html'>Jennifer made this excellent post about &lt;a href="telnet://well.com"&gt;The WELL&lt;/a&gt;:&lt;br /&gt;&lt;a href="http://fierce.jnfr.com/archives/2006/04/the_well_turns.html"&gt;http://fierce.jnfr.com/archives/2006/04/the_well_turns.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've been using The WELL since 1987, and it's been around since 1985. If you want to read about it on the web, read &lt;a href="http://www.well.com/"&gt;this&lt;/a&gt;, but if you want to use it, learn to use the command-line interface and and  connect to The WELL via SSH, not with a web browser.&lt;br /&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/history" rel="tag"&gt;history&lt;/a&gt;, &lt;a href="http://technorati.com/tag/The+WELL" rel="tag"&gt;The WELL&lt;/a&gt;, &lt;a href="http://technorati.com/tag/bulletin+boards" rel="tag"&gt;bulletin boards&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114394961394050891?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114394961394050891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114394961394050891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114394961394050891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114394961394050891'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/04/well-turns-21.html' title='The WELL Turns 21'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114373451679227192</id><published>2006-03-30T08:01:00.000-08:00</published><updated>2006-03-30T08:01:56.863-08:00</updated><title type='text'>Mini-Microsoft: Vista 2007. Fire the leadership now!</title><content type='html'>Fascinating stream of comments from many who appear to be Microsoft employees:&lt;br /&gt;&lt;a href="http://minimsft.blogspot.com/2006/03/vista-2007-fire-leadership-now.html"&gt;Mini-Microsoft: Vista 2007. Fire the leadership now!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114373451679227192?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114373451679227192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114373451679227192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114373451679227192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114373451679227192'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/03/mini-microsoft-vista-2007-fire.html' title='Mini-Microsoft: Vista 2007. Fire the leadership now!'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114339502601077353</id><published>2006-03-26T09:45:00.000-08:00</published><updated>2006-03-26T09:46:47.713-08:00</updated><title type='text'>Net Neutrality - where are we now?</title><content type='html'>Does this sound familiar:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;The battle is about who will build, own, use and pay for the high-speed data highways of the future and whether their content will be censored.&lt;/blockquote&gt;Roger Karraker wrote that in his 1991 article, "&lt;a href="gopher://gopher.well.com/00/Communications/Highways_of_the_Mind.txt"&gt;Highways of the Mind&lt;/a&gt;" and the article is still relevant today. Have a look.&lt;br /&gt;&lt;br /&gt;(See also: The &lt;a href="http://gopher.well.com:70/1/Communications"&gt;Communications section &lt;/a&gt;of The WELL gopher.)&lt;br /&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/net+neutrality" rel="tag"&gt;net neutrality&lt;/a&gt;, &lt;a href="http://technorati.com/tag/internet" rel="tag"&gt;internet&lt;/a&gt;, &lt;a href="http://technorati.com/tag/policy" rel="tag"&gt;policy&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114339502601077353?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114339502601077353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114339502601077353' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114339502601077353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114339502601077353'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/03/net-neutrality-where-are-we-now.html' title='Net Neutrality - where are we now?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114271104861028217</id><published>2006-03-18T11:43:00.000-08:00</published><updated>2006-03-18T12:04:35.263-08:00</updated><title type='text'>Perl BEGIN Blocks Considered Harmful</title><content type='html'>&lt;a href="http://ali.as/about.html"&gt;Adam Kennedy&lt;/a&gt; pointed this out to me:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Create a new Perl file containing the following:&lt;pre&gt;&lt;br /&gt;BEGIN {&lt;br /&gt;   print "hello world\n";&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Check the syntax with &lt;pre&gt;&lt;br /&gt;perl -c &lt;i&gt;filename&lt;/i&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;This will print &lt;span style="font-weight: bold;"&gt;hello world&lt;/span&gt;, even though &amp;quot;all&amp;quot; you did was compile the file.&lt;br /&gt;&lt;br /&gt;What's going on here?&lt;br /&gt;&lt;br /&gt;Well, BEGIN blocks get executed when Perl compiles the file.&lt;br /&gt;&lt;br /&gt;So what?&lt;br /&gt;&lt;br /&gt;If you run &lt;span style="font-style: italic;"&gt;&lt;code&gt;perl -c&lt;/code&gt;&lt;/span&gt; on a file that contains nasty code in a BEGIN block, you're screwed.&lt;br /&gt;&lt;br /&gt;Consider this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You associate the filename extension &lt;span style="font-weight: bold;"&gt;.pm&lt;/span&gt; with a fancy Perl editor, like &lt;a href="http://www.activestate.com/Products/Komodo/"&gt;Komodo&lt;/a&gt;,  or &lt;a href="http://www.latenightsw.com/affrus/"&gt;Affrus&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You click on a link in your web browser.&lt;/li&gt;&lt;li&gt;The web server redirects you to a URL for &lt;span style="font-weight: bold;"&gt;nasty_file.pm&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Your browser opens the associated editor and performs a"syntax check" by compiling the file&lt;/li&gt;&lt;li&gt;The file's &lt;span style="font-weight: bold;"&gt;BEGIN&lt;/span&gt; block has naughty code in it...&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;You're screwed.&lt;br /&gt;&lt;br /&gt;So, keep in mind that "just compiling" Perl code may actually execute the code, so, be careful!&lt;br /&gt;&lt;br /&gt;Here's a &lt;a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1435420&amp;amp;amp;group_id=75859&amp;amp;atid=545274"&gt;bug report&lt;/a&gt; on this subject that I filed for the &lt;a href="http://sourceforge.net/projects/e-p-i-c/"&gt;Eclipse/EPIC Perl IDE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;perl&lt;/a&gt;, &lt;a href="http://technorati.com/tag/security" rel="tag"&gt;security&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114271104861028217?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114271104861028217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114271104861028217' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114271104861028217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114271104861028217'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/03/perl-begin-blocks-considered-harmful.html' title='Perl BEGIN Blocks Considered Harmful'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114252682053394447</id><published>2006-03-16T08:27:00.000-08:00</published><updated>2006-03-18T12:07:32.623-08:00</updated><title type='text'>Testing if a Perl script compiles - compile_ok</title><content type='html'>A co-worker and I were pair programming a test suite the other day, and needed to test if a Perl script compiles - not a library or module but an executeable script, so the typical:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    require_ok()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    use_ok()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;functions provided by &lt;a href="http://search.cpan.org/%7Emschwern/Test-Simple-0.62/"&gt;Test::More&lt;/a&gt; don't do exactly what we wanted.&lt;br /&gt;&lt;br /&gt;The short story is that we ended up doing something like this:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;  eval {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;     $output = `perl -c $script 2&gt;&amp;1`;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;     chomp $output;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;  };&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;  is($output, "$script syntax OK", "$script compiles");&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;We later looked for a more general, better solution, and a colleague posted on the perl-qa mailing list, but the bottom line is that a more elegant solution still involves executing a new perl interpreter, but in a platform-independent way (perhaps using &lt;code&gt;IPC::Open3&lt;/code&gt; or something.) It's also likely that a better test is to ignore the output altogether and just check the return code from the compile process (the call to &lt;code&gt;perl -c&lt;/code&gt;.)&lt;br /&gt;&lt;blockquote style="color: rgb(0, 102, 0);"&gt;&lt;br /&gt;March 18, 2006 update: &lt;a href="http://search.cpan.org/%7Ethaljef/"&gt;Jeff Thalhammer&lt;/a&gt; found that a colleague &lt;a href="http://search.cpan.org/%7Epdenis/"&gt;Pierre Denis&lt;/a&gt; provides a &lt;a href="http://search.cpan.org/dist/Test-Strict/lib/Test/Strict.pm#syntax_ok%28_%24file_%5B%2C_%24text%5D_%29"&gt;syntax_ok&lt;/a&gt; method in &lt;a href="http://search.cpan.org/dist/Test-Strict/lib/Test/Strict.pm"&gt;Test::Strict&lt;/a&gt; that does what we want.&lt;br /&gt;More update - I was prodded by Randall Schwartz to post why you should be careful when "only" compiling Perl code - see &lt;a href="http://twoalpha.blogspot.com/2006/03/perl-begin-blocks-considered-harmful.html"&gt;BEGIN Blocks Considered Harmful&lt;/a&gt;.&lt;br /&gt;&lt;/blockquote&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;perl&lt;/a&gt;, &lt;a href="http://technorati.com/tag/testing" rel="tag"&gt;testing&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114252682053394447?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114252682053394447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114252682053394447' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114252682053394447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114252682053394447'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/03/testing-if-perl-script-compiles.html' title='Testing if a Perl script compiles - compile_ok'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114252626453403457</id><published>2006-03-16T08:24:00.000-08:00</published><updated>2006-03-16T08:26:02.696-08:00</updated><title type='text'>Swimming Snake Robot</title><content type='html'>OK, ready to be creeped-out and fascinated?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.hackaday.com/entry/1234000957073583/"&gt;http://www.hackaday.com/entry/1234000957073583/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114252626453403457?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114252626453403457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114252626453403457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114252626453403457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114252626453403457'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/03/swimming-snake-robot.html' title='Swimming Snake Robot'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114079925727371081</id><published>2006-02-24T08:40:00.000-08:00</published><updated>2006-02-24T08:43:56.946-08:00</updated><title type='text'>Teen Use of MySpace</title><content type='html'>A transcript of a rather cogent and articulate talk by Danah Boyd on &lt;a href="http://www.danah.org/papers/AAAS2006.html"&gt;teen use of MySpace.com&lt;/a&gt;:&lt;br /&gt;&lt;a href="http://www.danah.org/papers/AAAS2006.html"&gt;http://www.danah.org/papers/AAAS2006.html&lt;/a&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/teens" rel="tag"&gt;teens&lt;/a&gt;, &lt;a href="http://technorati.com/tag/myspace" rel="tag"&gt;myspace&lt;/a&gt;, &lt;a href="http://technorati.com/tag/psychology" rel="tag"&gt;psychology&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114079925727371081?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114079925727371081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114079925727371081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114079925727371081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114079925727371081'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/teen-use-of-myspace.html' title='Teen Use of MySpace'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114054113934574319</id><published>2006-02-21T08:48:00.000-08:00</published><updated>2006-02-21T08:58:59.346-08:00</updated><title type='text'>RFC: Mozilla Architecture Changes</title><content type='html'>&lt;a href="http://www.daveliebreich.com/blog/"&gt;Dave Liebreich&lt;/a&gt; is looking for people to participate in conversations about proposed major changes in the architecture of &lt;a href="http://mozilla.com/"&gt;Mozilla.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dave provided the following URLs for current discussions about the issues (garbage collection approach and using exceptions) and asks that interested people jump in and participate:&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://wiki.mozilla.org/User:Davel/Comment_Staging_Area"&gt;Mozilla Wiki&lt;/a&gt;&lt;br /&gt;&lt;a href="http://weblogs.mozillazine.org/roadmap/archives/009727.html"&gt;Mozillazine.org&lt;/a&gt;&lt;br /&gt;&lt;a href="http://benjamin.smedbergs.us/blog/2006-02-18/exceptions-dont-solve-the-problem/"&gt;Benjamin Smedbergs on Exceptions&lt;/a&gt;&lt;br /&gt;&lt;a href="http://benjamin.smedbergs.us/blog/2006-02-18/xpcom-detecting-reference-cycles-or-switching-to-gc/"&gt;                   Benjamin Smedbergs on Garbage Collection&lt;/a&gt;&lt;br /&gt;                  &lt;/blockquote&gt;&lt;http:&gt;&lt;http: problem=""&gt;&lt;http: gc=""&gt;&lt;http:&gt; &lt;/http:&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/mozilla" rel="tag"&gt;Mozilla&lt;/a&gt;, &lt;a href="http://technorati.com/tag/XPCOM" rel="tag"&gt;XPCOM&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114054113934574319?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114054113934574319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114054113934574319' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114054113934574319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114054113934574319'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/rfc-mozilla-architecture-changes.html' title='RFC: Mozilla Architecture Changes'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114054018255388828</id><published>2006-02-21T08:43:00.000-08:00</published><updated>2006-02-21T08:47:40.326-08:00</updated><title type='text'>Should Arab Media Take Lessons from the West?</title><content type='html'>An &lt;a href="http://www.thedohadebates.com/output/Page52.asp"&gt;excellent debate among journalists&lt;/a&gt; from and working in the Arab world, debating the motion "This house believes that the Arab media need no lessons in journalism from the West."&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/Journalism" rel="tag"&gt;Journalism&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Media" rel="tag"&gt;Media&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Middle+East" rel="tag"&gt;Middle East&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Arab-Israeli+Conflict" rel="tag"&gt;Arab-Israeli Conflict&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114054018255388828?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114054018255388828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114054018255388828' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114054018255388828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114054018255388828'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/should-arab-media-take-lessons-from.html' title='Should Arab Media Take Lessons from the West?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114028215504068164</id><published>2006-02-18T09:01:00.000-08:00</published><updated>2006-02-18T09:02:35.076-08:00</updated><title type='text'>Bunchball - put interactive stuff in your blog</title><content type='html'>&lt;a href="http://www.bunchball.com/"&gt;http://www.bunchball.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The idea is you put a code snippet in your web page, blog etc. and then you can upload photos etc. to bunchballs servers and they show up in your page. Also does games, and various other interactive thingies.&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/flash" rel="tag"&gt;flash&lt;/a&gt;, &lt;a href="http://technorati.com/tag/interactive" rel="tag"&gt;interactive&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114028215504068164?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114028215504068164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114028215504068164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114028215504068164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114028215504068164'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/bunchball-put-interactive-stuff-in.html' title='Bunchball - put interactive stuff in your blog'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-114019222871478695</id><published>2006-02-17T08:06:00.000-08:00</published><updated>2006-02-18T10:47:31.076-08:00</updated><title type='text'>Perl IDE Demonstration and Comparison</title><content type='html'>The &lt;a href="http://sf.pm.org/"&gt;San Francisco Perl Mongers&lt;/a&gt; are sponsoring a &lt;a href="http://sf.pm.org/weblog/archives/00000031.html"&gt;demo of three Perl IDE's on Tuesday, February 28&lt;/a&gt;, 2006:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Emacs - Joe Brenner will show Emacs with &lt;a href="http://obsidianrook.com/perlnow/"&gt;perlnow.el&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://e-p-i-c.sourceforge.net/"&gt;EPIC/Eclipse&lt;/a&gt; - I'll be doing this demo. (See my article on why &lt;a href="http://www.eigenstate.net/perl_tools/"&gt;Perl Needs Better Tools&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Komodo - Josh Berkus is showing &lt;a href="http://www.activestate.com/Products/Komodo/"&gt;ActiveState's Komodo&lt;/a&gt; (works on Linux, OS X and Windows)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;When &amp; Where: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When&lt;/span&gt;: Tuesday, February 28, 2006, 8:00 p.m.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Where&lt;/span&gt;: Perpetual Entertainment, Fifth floor;&lt;br /&gt;&lt;a href="http://tinyurl.com/96592"&gt;149 New Montgomery Street, San Francisco, CA&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;RSVP&lt;/span&gt;: &lt;a href="mailto:qw@sf.pm.org"&gt;qw@sf.pm.org&lt;/a&gt; - please let us know if you are attending, and if you want thai food, bring some $$&lt;br /&gt;&lt;br /&gt;If you would like to attend, please contact Quinn Weaver at the address above - and bring cash if you want Thai food!&lt;br /&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/IDE" rel="tag"&gt;IDE&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Perl" rel="tag"&gt;Perl&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Eclipse" rel="tag"&gt;Eclipse&lt;/a&gt;, &lt;a href="http://technorati.com/tag/EPIC" rel="tag"&gt;EPIC&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Komodo" rel="tag"&gt;Komodo&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-114019222871478695?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/114019222871478695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=114019222871478695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114019222871478695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/114019222871478695'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/perl-ide-demonstration-and-comparison.html' title='Perl IDE Demonstration and Comparison'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113968164464056344</id><published>2006-02-12T09:34:00.000-08:00</published><updated>2006-02-13T22:39:22.240-08:00</updated><title type='text'>Lets Make A Deal Game Theory</title><content type='html'>&lt;span style="color: rgb(153, 153, 153);"&gt;(originally posted 10:08 AM, Feb 11, 2006)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A couple days ago (yes, in a bar) I became intrigued with a fairly well known game problem, here's my version:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;There are three doors, one of which is a winner.&lt;/li&gt;&lt;li&gt;You pick one door, but it isn't opened yet.&lt;/li&gt;&lt;li&gt;At this point at least one of the unpicked doors (maybe both) are losers.&lt;/li&gt;&lt;li&gt;A losing unpicked door is opened.&lt;/li&gt;&lt;li&gt;You now have the option of either sticking with your original choice, or switching to the remaining unopened door. Which has a better chance of being the winner?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Here is a Perl script I wrote which will play the game using both the "switch" and "stay" strategies: &lt;a href="http://eigenstate.net/misc_scripts/make_a_deal.pl"&gt;http://eigenstate.net/misc_scripts/make_a_deal.pl&lt;/a&gt; &lt;div class="tag_list"&gt;&lt;br /&gt;What do you think?&lt;br /&gt;&lt;br /&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/game+theory" rel="tag"&gt;game theory&lt;/a&gt;, &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;perl&lt;/a&gt;, &lt;a href="http://technorati.com/tag/lets+make+a+deal" rel="tag"&gt;lets make a deal&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;12 Feb 2006 - addition:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is one way of explaining what is going on:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When the losing choice is revealed, you gain some new information.&lt;br /&gt;&lt;br /&gt;At the start, you have equal knowledge of all the choices, so at first every door has 1/n chance (1/3 if there are three doors).&lt;br /&gt;&lt;br /&gt;You then divide doors into two groups: one door in group A (your first pick) and the rest of the doors in group B. With three doors group A carries 1/3 of the chances and group B carries 2/3.&lt;br /&gt;&lt;br /&gt;When one of the doors in group B is revealed to be a loser you know something new:&lt;br /&gt;&lt;br /&gt;You know that the group of chances that was in group B at the start must now be redistributed among the &lt;span style="font-weight: bold;"&gt;remaining&lt;/span&gt; doors in group B.&lt;br /&gt;&lt;br /&gt;So if group B had 2/3 of the chances at the start, it *still has* 2/3 of the chances, but those all ride on the one remaining door in group B. So, the remaining door in group B has a 2/3 chance fo winning, whilst the door you originally picked, in group A still has only a 1/3 chance.&lt;br /&gt;&lt;br /&gt;What has happend is that the revelation of the loser in group B has told you that all the other doors in group are more likely to be a winner.&lt;br /&gt;&lt;br /&gt;If you try it with 10 doors it is still better to switch - to pick any remaining door in group B - than to stay with the door in group A.&lt;br /&gt;&lt;br /&gt;Where N is the number of doors, the chance of the first pick winning is &lt;span style="font-style: italic;font-family:courier new;" &gt;1/N&lt;/span&gt;, and the chance of a door in group B &lt;span style="font-weight: bold;"&gt;after eliminating a loser from group B&lt;/span&gt; is&lt;span style="font-style: italic;"&gt;:  &lt;span style="font-family:courier new;"&gt;(N-1)/N&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="tags"&gt;It is the &lt;span style="font-style: italic; color: rgb(0, 0, 0);font-family:courier new;font-size:130%;"  &gt;-1&lt;/span&gt; that makes swicthing worth it.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="tags"&gt;We can generalize the problem further by saying that &lt;span style="font-style: italic;font-family:courier new;" &gt;T&lt;/span&gt; is the Total number of doors, &lt;span style="font-style: italic;font-family:courier new;" &gt;A&lt;/span&gt; is the number of doors in group A, and &lt;span style="font-style: italic;font-family:courier new;" &gt;B&lt;/span&gt; is the number in group B before a loser is revealed. Then the chance of a door in group A is &lt;span style="font-style: italic;font-family:courier new;" &gt;A/T&lt;/span&gt; (for example, 1/3)  and the chance of a door in group B, after the elimination is &lt;span style="font-style: italic;font-family:courier new;" &gt;B - 1 / T&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So if there are 10 door total, and you put 3 doors in group A at the start:&lt;br /&gt;&lt;br /&gt;T = 10&lt;br /&gt;A = 3&lt;br /&gt;B = 7&lt;br /&gt;&lt;br /&gt;Each group A door has a 1/10 chance (3/10 for the group as a whole.) After eliminating a loser from group B, &lt;span style="font-style: italic;"&gt;the group as a whole still has 7/10 chances and thus &lt;/span&gt;each remaining group B door has  a &lt;strike&gt;6/10&lt;/strike&gt; 11 2/3% chance of being the winner. (thanks to &lt;a href="http://www.blogger.com/profile/8233786"&gt;keith&lt;/a&gt; for the correction)&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113968164464056344?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113968164464056344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113968164464056344' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113968164464056344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113968164464056344'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/lets-make-deal-game-theory.html' title='Lets Make A Deal Game Theory'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113950436596682900</id><published>2006-02-09T08:52:00.000-08:00</published><updated>2006-02-09T09:01:47.470-08:00</updated><title type='text'>Unit tests for Mozilla / Firefox coming soon</title><content type='html'>&lt;a href="http://www.daveliebreich.com/blog/"&gt;Dave Liebreich&lt;/a&gt; of &lt;a href="http://mozilla.com/"&gt;Mozilla.com&lt;/a&gt; has &lt;a href="http://lxr.mozilla.org/seamonkey/source/tools/test-harness/jssh-driver"&gt;posted the source code&lt;/a&gt; for &lt;a href="http://www.google.com/search?q=jssh-driver"&gt;jssh-driver&lt;/a&gt; - a unit test framework for use in Mozilla browsers, (e.g. Firefox). This little framework will allow you to have a directory of HTML files, and test if the browser renders them correctly. Basically the test loads the "golden master" versions into the browser and compares the rendered version to the version on disk. (When the browser renders an HTML page it takes it apart and puts it back together - hopefully correctly.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/mozilla" rel="tag"&gt;mozilla&lt;/a&gt;, &lt;a href="http://technorati.com/tag/firefox" rel="tag"&gt;firefox&lt;/a&gt;, &lt;a href="http://technorati.com/tag/testing" rel="tag"&gt;testing&lt;/a&gt;, &lt;a href="http://technorati.com/tag/unit+tests" rel="tag"&gt;unit tests&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113950436596682900?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113950436596682900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113950436596682900' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113950436596682900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113950436596682900'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/unit-tests-for-mozilla-firefox-coming.html' title='Unit tests for Mozilla / Firefox coming soon'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113889868111471783</id><published>2006-02-02T08:44:00.000-08:00</published><updated>2006-02-04T19:57:13.470-08:00</updated><title type='text'>US Internet biz profits from oppression</title><content type='html'>&lt;a href="http://www.washingtonpost.com/wp-dyn/content/article/2006/02/01/AR2006020101636.html"&gt;From the Washington Post&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;House: Internet Companies Give in to China&lt;br /&gt;&lt;br /&gt;By FOSTER KLUG&lt;br /&gt;The Associated Press&lt;br /&gt;Wednesday, February 1, 2006; 10:37 PM&lt;br /&gt;&lt;br /&gt;WASHINGTON -- Lawmakers on Wednesday accused U.S.-based Internet companies of&lt;br /&gt;giving in to pressure from China and helping to censor Web users in violation&lt;br /&gt;of American principles of free speech.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;I think it's disgusting that these companies are seeking to profit from cooperation with oppression while simultaneously benefiting from the freedoms afforded them here in the US.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113889868111471783?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113889868111471783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113889868111471783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113889868111471783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113889868111471783'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/us-internet-biz-profits-from.html' title='US Internet biz profits from oppression'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113881206028371245</id><published>2006-02-01T08:36:00.000-08:00</published><updated>2006-02-05T18:34:08.980-08:00</updated><title type='text'>More tests, fewer bugs</title><content type='html'>Mozilla is looking for a few good test-driven engineers...&lt;br /&gt;&lt;br /&gt;I visited the &lt;a href="http://www.mozilla.com/"&gt;Mozilla Corporation&lt;/a&gt; offices yesterday, at the invitation of &lt;a href="http://www.daveliebreich.com/blog/"&gt;Dave Liebreich&lt;/a&gt;, who is heading up the effort to bring more testing to the Mozilla code base. There is a wiki page: &lt;a href="http://wiki.mozilla.org/SoftwareTesting"&gt;http://wiki.mozilla.org/SoftwareTesting &lt;/a&gt;describing some projects and ideas. Dave is a good guy doing good work - let's help!&lt;br /&gt;&lt;div class="tag_list"&gt;Tags: &lt;span class="tags"&gt;&lt;a href="http://technorati.com/tag/Mozilla" rel="tag"&gt;Mozilla&lt;/a&gt;, &lt;a href="http://technorati.com/tag/testing" rel="tag"&gt;testing&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113881206028371245?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113881206028371245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113881206028371245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113881206028371245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113881206028371245'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/02/more-tests-fewer-bugs.html' title='More tests, fewer bugs'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113872344553105213</id><published>2006-01-31T08:04:00.000-08:00</published><updated>2006-02-01T08:29:29.673-08:00</updated><title type='text'>Concrete Canvas</title><content type='html'>&lt;a href="http://www.concretecanvas.org.uk/"&gt;http://www.concretecanvas.org.uk/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Instant semi-permanent structure.&lt;br /&gt;Fill bag with water, activate chemical gas-pack, it inflates and hardens and is ready for use in 12-hours.&lt;br /&gt;&lt;br /&gt;Update (1 Feb 2006):&lt;br /&gt;My friend and &lt;a rel="tag" href="http://technorati.com/tag/architecture"&gt;architect&lt;/a&gt; Bob Theis (&lt;a href="http://www.bobtheis.net/"&gt;http://www.bobtheis.net/&lt;/a&gt;) raised these important issues:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;blockquote style="color: rgb(0, 102, 0);"&gt;&lt;span style="font-family:verdana;"&gt;Clever idea. Two reactions:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;1. Hard to imagine a shell that thin being dimensionally stable enough for such a span in compression (  how does it resist local buckling? ).  ESPECIALLY when you cover it with earth to gain some insulation ( see below ).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;2. The plastic sheet interior would condense ALL the water vapor that hits it when the temperature outside is low ( despite the website claims, the insulation value of the skin should be next to nil ), where it would then freeze in colder situations. So insulation and ventilation would be serious habitability issues.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113872344553105213?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113872344553105213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113872344553105213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113872344553105213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113872344553105213'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/01/concrete-canvas.html' title='Concrete Canvas'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113728309877810878</id><published>2006-01-14T16:10:00.000-08:00</published><updated>2006-01-14T16:12:29.743-08:00</updated><title type='text'>Adding Assertions in Perl</title><content type='html'>I've been working on a Perl module that provides a set of assertion methods that will work in Perl 5.6.1 or later. (Note that Perl 5.10 should have some form of &lt;a href="http://www.oreillynet.com/pub/wlg/8894"&gt;builtin support for assertions&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;So far I've implemented:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;assert( expr, $optional_message );  # passes if expr is true&lt;br /&gt;assert_is($$this,$that, $opt_msg); # compare with eq&lt;br /&gt;assert_isnt($this,$that, $opt$msg); # Compare with ne&lt;br /&gt;&lt;br /&gt;# all values must be == to each other&lt;br /&gt;assert_num_equals($arrayref, $opt_msg);&lt;br /&gt;&lt;br /&gt;save_data($key, $ref_to_data); # saves clone of data&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;# Assert that some data has (or not) the same values as the&lt;br /&gt;# previsouly saved data - does a deep compare.&lt;/code&gt;&lt;br /&gt;&lt;code&gt;assert_data_not_different($key,$ref_to_data, $opt_msg);&lt;br /&gt;&lt;/code&gt;&lt;code&gt;assert_data_different($key,$ref_to_data, $opt_msg);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I've also implemented methods to set the pass and fail behaviors:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set_pass_behavior('silence');&lt;br /&gt;set_pass_behavior('warn');&lt;br /&gt;set_pass_behavior( \&amp;my_sub ); # CODE ref&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;set_fail_behavior('silence');&lt;br /&gt;set_fail_behavior('warn');&lt;br /&gt;set_fail_behavior('confess'); #die with stack trace&lt;br /&gt;set_fail_behavior( \&amp;my_sub ); # CODE ref&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I'm doing this for a client and am not sure if we'll be allowed to release the code publicly, but I hope so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113728309877810878?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113728309877810878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113728309877810878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113728309877810878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113728309877810878'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/01/adding-assertions-in-perl.html' title='Adding Assertions in Perl'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113665344064284580</id><published>2006-01-07T08:46:00.000-08:00</published><updated>2006-01-07T09:04:00.736-08:00</updated><title type='text'>Adding Unit Tests to Legacy Code</title><content type='html'>I've started adding Unit Tests to a "legacy" code library. So far, the basic approach I am taking is:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create the test harness.&lt;/li&gt;&lt;li&gt;The first test is to compile the old code library. Of course that fails at first because of all the things the library depends on.&lt;/li&gt;&lt;li&gt;Create enough "fake" class files that the library compiles.&lt;/li&gt;&lt;li&gt;Pick one subroutine (method) to test, and add a test that runs that subroutine. Of course it fails because of all the missing dependencies - the subroutine under test uses a bunch of subroutines defined in others.&lt;/li&gt;&lt;li&gt;In the test suite, create a FakeMethods class that defines stub versions of the missing external methods/subroutines, for example, the subroutine I am testing calls GetTotalAmount($cost,@items) so in the test suite I have something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sub GetTotalAmount {&lt;br /&gt; cluck('fake sub called');  # Print a stack trace showing we were called&lt;br /&gt; my($cost,@items) = @_;     # Document the arguments expected&lt;br /&gt; return;                    # Return nothing for now&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Some of the fake subroutines will need to return some actual values for the subroutine I am testing to run. Add &lt;span style="font-style: italic;"&gt;just enough input&lt;/span&gt; so the test passes, even when this seems ridiculous. For example, I found that one subroutine wanted the name of a file to open, and that the subroutine would run even if I passed in the name of a non-existent file. OK, that's what I did. Later, we can add a test expecting the subroutine to throw an exception if the file doesn't exist, and then add defensive code to throw the subroutine.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Continue repeating steps 5 and 6 until the subroutine I am testing runs without throwing an exception.&lt;/li&gt;&lt;li&gt;Add tests to run the subroutine with variations on its arguments and/or environment. I may need to add more fake subroutines, mock data, etc.&lt;/li&gt;&lt;li&gt;The result is that I have a pretty clearly documented view of what the subroutine/method actually requires to run as of today.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113665344064284580?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113665344064284580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113665344064284580' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113665344064284580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113665344064284580'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2006/01/adding-unit-tests-to-legacy-code.html' title='Adding Unit Tests to Legacy Code'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113601153606063547</id><published>2005-12-30T22:41:00.000-08:00</published><updated>2005-12-30T22:45:36.073-08:00</updated><title type='text'>Semco and Ricardo Semler - Agile Industry?</title><content type='html'>Some Semco links:&lt;br /&gt;&lt;br /&gt;CNN, 2004:&lt;br /&gt;&lt;a href="http://edition.cnn.com/2004/BUSINESS/05/19/go.semlar.transcript/"&gt;http://edition.cnn.com/2004/BUSINESS/05/19/go.semlar.transcript/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Excerpt from Semler's 2004 book "The Seven-Day Weekend"&lt;br /&gt;&lt;a href="http://www.nfib.com/object/4243663.html"&gt;http://www.nfib.com/object/4243663.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Wikipedia entry on Ricardo Semler:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Ricardo_Semler"&gt;http://en.wikipedia.org/wiki/Ricardo_Semler&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;An excellent interview with Semler by CIO Insight, unfortunately dated April 1, 2004:&lt;br /&gt;&lt;a href="http://www.cioinsight.com/print_article2/0,1217,a=124700,00.asp"&gt;http://www.cioinsight.com/print_article2/0,1217,a=124700,00.asp&lt;/a&gt;&lt;br /&gt;Very good stuff about corporate email privacy, among other issues, here's an excerpt from Semler:&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-style: italic;font-family:georgia;" &gt;&lt;blockquote&gt;...we searched far and wide for anybody who could tell us what kind of software or system could be installed on our [server] that would make it impossible for our own IT people to spy on people's e-mail. We did not find one. We had to customize one.&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113601153606063547?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113601153606063547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113601153606063547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113601153606063547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113601153606063547'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/12/semco-and-ricardo-semler-agile.html' title='Semco and Ricardo Semler - Agile Industry?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113535957292288255</id><published>2005-12-23T09:33:00.000-08:00</published><updated>2009-03-02T08:38:16.004-08:00</updated><title type='text'>Working Effectively With Legacy Code</title><content type='html'>I'm preparing for a new contract (with Barclays Global Investors) where I'll be helping to improve a software developemnt process in a group that has many years of existing code, so I've been reading &lt;a class="bookCredits"&gt;Michael Feathers&lt;/a&gt;         new book "Working Effectively with Legacy Code" (&lt;a href="http://www.objectmentor.com/resources/bookstore/books/welc"&gt;http://my.safaribooksonline.com/0131177052)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So far, I really like the book - it quite modern, coming from an agile/XP approach and consistently emphasizes that the basic task is to get the legacy code under a test harness, so that changes can be made with fewer ulcers.&lt;br /&gt;&lt;br /&gt;The book goes into many different examples of how existing code is resistant to being testable, and then shows (usually two or more) approaches for overcoming or workign around those problems.&lt;br /&gt;&lt;br /&gt;Another reason I like that the book is that Feathers consistently emphasizes how hard this is - no magic solutions, ugly compromises often required, etc. but that you can make big progess out of many small steps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113535957292288255?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113535957292288255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113535957292288255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113535957292288255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113535957292288255'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/12/working-effectively-with-legacy-code.html' title='Working Effectively With Legacy Code'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113008842975499210</id><published>2005-11-27T09:40:00.000-08:00</published><updated>2005-11-27T09:39:46.643-08:00</updated><title type='text'>Unit Testing in Perl with Test::Unit</title><content type='html'>I've come to prefer &lt;a href="http://search.cpan.org/dist/Test-Unit/"&gt;Test::Unit&lt;/a&gt; over &lt;a href="http://search.cpan.org/dist/Test-More/"&gt;Test::More&lt;/a&gt;. The main reason is that in Test::Unit you define each test as a separate subroutine, so the variables used for one test cannot pollute another test.&lt;br /&gt;&lt;br /&gt;Test::More is a widely used module for Unit Tests in Perl. With Test::More your tests look like this:&lt;br /&gt;&lt;pre&gt;# Test method_a()&lt;br /&gt;my &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_1&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;23 * $CONSTANT; # some value we expect&lt;/span&gt;;&lt;br /&gt;is( &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_1&lt;/span&gt;, $object-&gt;method_a(23),&lt;br /&gt;   "&lt;span style="color: rgb(0, 0, 153);"&gt;method_a(23) returned expected value.&lt;/span&gt;");&lt;br /&gt;&lt;br /&gt;my&lt;span style="color: rgb(204, 51, 204);"&gt; $expected_2&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;17 * $CONSTANT&lt;/span&gt;; # A new expected value&lt;br /&gt;is( &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_2&lt;/span&gt;, $object-&gt;method_a(17),&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;   "method_a(17) returned expected value"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;# Test another_method()&lt;br /&gt;my&lt;span style="color: rgb(204, 51, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;$expected_3&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;_get_favorite_color();&lt;/span&gt;&lt;br /&gt;is( &lt;span style="color: rgb(204, 51, 204);"&gt;$&lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;expected_3&lt;/span&gt;, $object-&gt;another_method('favorite'),&lt;br /&gt;   "&lt;span style="color: rgb(0, 0, 153);"&gt;another_method('favorite') returned proper color.&lt;/span&gt;");&lt;br /&gt;&lt;br /&gt;my&lt;span style="color: rgb(204, 51, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;$expected_4&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;_get_recent_color();&lt;/span&gt;&lt;br /&gt;is( &lt;span style="color: rgb(204, 51, 204);"&gt;$&lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;expected_4&lt;/span&gt; $object-&gt;another_method('recent'),&lt;br /&gt;   "&lt;span style="color: rgb(0, 0, 153);"&gt;another_method('recent') returned proper color.&lt;/span&gt;");&lt;br /&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;See how we need to come up with many versions of the &lt;span style="color: rgb(204, 51, 204);"&gt;&lt;code&gt;$expected&lt;/code&gt;&lt;/span&gt; variable?&lt;br /&gt;&lt;br /&gt;We could also just reuse it, but that can cause trouble if there are many tests and you forget to reset it.&lt;br /&gt;&lt;br /&gt;It is better practice to use a different variable name for each test, but in many situations there are a couple dozen tests in that one file where it makes sense to use the same basic variable name for many different tests. That could lead to variable names like &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_100&lt;/span&gt;. Also, there is always the risk that some temporary variables used for one test end up "polluting" a later test where the programmer didn't realize a variable was already defined earlier in the file.&lt;br /&gt;&lt;br /&gt;The best solution is to isolate the code for each test, or small group of related tests into their own block, so that temporary variables for one test cannot interfere with another test or tests.&lt;br /&gt;&lt;br /&gt;In &lt;strong&gt;Test::Unit&lt;/strong&gt; each test is a subroutine, which can contain any number of assertions - so all the temporary variables and other setup for a particular group of tests are kept isolated from all the other tests. In addition, if you provide a subroutine called set_up() it is automatically called before running each test subroutine, and likewise, tear_down() is called after each test, this is useful for populating objects and test data structures, so that each test gets a clean set of test data to work with.&lt;br /&gt;&lt;br /&gt;In &lt;strong&gt;Test::Unit&lt;/strong&gt; the tests above might look like this:&lt;br /&gt;&lt;pre&gt;sub test_method_a {&lt;br /&gt;my $self = shift;&lt;br /&gt;&lt;br /&gt;my &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_1&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;23 * $CONSTANT; # some value we expect&lt;/span&gt;;&lt;br /&gt;$self-&gt;assert_equals( &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_1&lt;/span&gt;, $object-&gt;method_a(23));&lt;br /&gt;&lt;br /&gt;my &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_2 &lt;/span&gt;= &lt;span style="color: rgb(0, 0, 153);"&gt;17 * $CONSTANT;&lt;/span&gt;&lt;br /&gt;$self-&gt;assert_equals( &lt;span style="color: rgb(204, 51, 204);"&gt;$expected_2&lt;/span&gt;, $object-&gt;method_a(17));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub test_another_method {&lt;br /&gt;my $self = shift;&lt;br /&gt;&lt;br /&gt;my&lt;span style="color: rgb(204, 51, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;$expected_1&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;_get_favorite_color();&lt;/span&gt;&lt;br /&gt;$self-&gt;assert_equals(&lt;span style="color: rgb(204, 51, 204);"&gt;$&lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;expected_1&lt;/span&gt;, $object-&gt;another_method('favorite'));&lt;br /&gt;&lt;br /&gt;my&lt;span style="color: rgb(204, 51, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;$expected_2&lt;/span&gt; = &lt;span style="color: rgb(0, 0, 153);"&gt;_get_recent_color();&lt;/span&gt;&lt;br /&gt;$self-&gt;assert_equals(&lt;span style="color: rgb(204, 51, 204);"&gt;$&lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;expected_2&lt;/span&gt;, $object-&gt;another_method('recent'));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Test::Unit&lt;/strong&gt; provides a bunch of assertion methods:&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;&lt;code&gt;assert_equals&lt;/code&gt; / &lt;code&gt;assert_not_equals&lt;/code&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Tries to guess what kind of comparison to make. Usually works fine. If the first argument (the 'expected') is an object it checks if the &lt;code&gt;==&lt;/code&gt; operator has been overloaded and will use it if so.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;&lt;code&gt;assert_num_equals&lt;/code&gt;,&lt;code&gt;assert_num_not_equals&lt;/code&gt;,&lt;code&gt;assert_str_equals&lt;/code&gt;,&lt;code&gt;assert_str_equals&lt;/code&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Force numeric/string comparison.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;&lt;code&gt;assert_matches(qr/PATTERN/, STRING, [, MESSAGE])&lt;/code&gt;, &lt;code&gt;assert_not_matches&lt;/code&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Assert that the regular expression matches.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;&lt;code&gt;assert_deep_equals(expected_ref, ref_to_test [, MESSAGE ])&lt;/code&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Used to compare complex data strucrtures, like hashes of arrays of hashes. Assert that the the data pointed to by &lt;em&gt;ref_to_test&lt;/em&gt; matches the data structure pointed to by &lt;em&gt;expected_ref&lt;/em&gt;&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;See also:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oreilly.com/catalog/perltestingadn/"&gt;Perl Testing: A Developer's Notebook&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.perl.com/pub/a/2005/08/25/tools.html"&gt;Perl Needs Better Tools&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Tags: &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;perl&lt;/a&gt;,&lt;a href="http://technorati.com/tag/unit+tests" rel="tag"&gt;unit tests&lt;/a&gt;,&lt;a href="http://technorati.com/tag/programming" rel="tag"&gt;programming&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113008842975499210?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113008842975499210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113008842975499210' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113008842975499210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113008842975499210'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/11/unit-testing-in-perl-with-testunit.html' title='Unit Testing in Perl with Test::Unit'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113116108638487506</id><published>2005-11-04T19:20:00.000-08:00</published><updated>2005-11-27T08:46:22.033-08:00</updated><title type='text'>Perl Best Practices</title><content type='html'>Damian Conway's new book, &lt;a href="http://www.oreilly.com/catalog/perlbp"&gt;Perl Best Practices&lt;/a&gt; is a very good, thought provoking, and useful addition to any Perl programmer's collection.&lt;br /&gt;&lt;br /&gt;From my point of view, the best thing about the book is that it provides a lot of food for thought - even if one disagrees with particular recommendations I think all the suggestions in the book areworth thinking about, and I am certain almost any reader will discover improvements they can make in their code and approaching to coding.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;perl&lt;/a&gt;, &lt;a href="http://technorati.com/tag/programming" rel="programming"&gt;perl&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113116108638487506?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113116108638487506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113116108638487506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113116108638487506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113116108638487506'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/11/perl-best-practices.html' title='Perl Best Practices'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113043124239728184</id><published>2005-10-27T09:39:00.000-07:00</published><updated>2005-10-27T09:42:18.273-07:00</updated><title type='text'>vi cheat sheets</title><content type='html'>Was going to email this list of vi cheat-sheets to a co-worker, but I'll post instead:&lt;br /&gt;&lt;a href="http://www.kcomputing.com/vi.html"&gt;&lt;br /&gt;http://www.kcomputing.com/vi.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cac.uvi.edu/miscfaq/vi-cheat.html"&gt;http://cac.uvi.edu/miscfaq/vi-cheat.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ase.tufts.edu/mechanical/compstudio/help/vihelp.html"&gt;http://ase.tufts.edu/mechanical/compstudio/help/vihelp.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(that list is from page 164 of &lt;a href="http://www.matisse.net/OSX/"&gt;my book&lt;/a&gt;.... :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113043124239728184?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113043124239728184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113043124239728184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113043124239728184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113043124239728184'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/vi-cheat-sheets.html' title='vi cheat sheets'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113012750504409955</id><published>2005-10-23T21:12:00.000-07:00</published><updated>2005-10-27T09:45:50.443-07:00</updated><title type='text'>PHP Comes to Eclipse</title><content type='html'>&lt;a href="http://www.computerworld.com/blogs/brown"&gt;Martin Brown&lt;/a&gt; blogged about &lt;a href="http://www.computerworld.com/blogs/node/1168"&gt;PHP coming to the Eclipse platform&lt;/a&gt; (back on Oct. 18th.) This interests me because I find that &lt;a href="http://technorati.com/tag/eclipse" rel="tag"&gt;Eclipse&lt;/a&gt; currently is the best cross-platform &lt;a href="http://technorati.com/tag/ide" rel="tag"&gt;IDE&lt;/a&gt; for &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;Perl&lt;/a&gt;, a language I like very much. (See my article at perl.com, "&lt;a href="http://www.perl.com/pub/a/2005/08/25/tools.html"&gt;Perl Needs Better Tools&lt;/a&gt;")&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113012750504409955?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113012750504409955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113012750504409955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113012750504409955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113012750504409955'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/php-comes-to-eclipse.html' title='PHP Comes to Eclipse'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-113008590575240515</id><published>2005-10-23T09:45:00.000-07:00</published><updated>2005-10-23T09:57:33.313-07:00</updated><title type='text'>Wargaming - another way of modeling the universe</title><content type='html'>I found a reference to myself in &lt;a href="http://www.livejournal.com/users/wombat_socho/"&gt;Kevin Trainor's blog&lt;/a&gt;, Wombat Rampant. The &lt;a href="http://www.livejournal.com/users/wombat_socho/255067.html"&gt;posting is about the decline of paper-based combat simulation games&lt;/a&gt;. Back in the 1970's I used to design and play &lt;a href="http://technorati.com/tag/wargames" rel="tag"&gt;wargames&lt;/a&gt;, which to me, are part of my lifelong involvement with building things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-113008590575240515?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/113008590575240515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=113008590575240515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113008590575240515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/113008590575240515'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/wargaming-another-way-of-modeling.html' title='Wargaming - another way of modeling the universe'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112999765591677600</id><published>2005-10-22T09:15:00.000-07:00</published><updated>2005-10-22T09:29:22.343-07:00</updated><title type='text'>Take Control of Permissions in Mac OS X</title><content type='html'>My long-time friend and colleague &lt;a href="http://www.briantanaka.com/"&gt;Brian Tanaka&lt;/a&gt; has written a new eBook "&lt;a href="http://www.takecontrolbooks.com/permissions-macosx.html"&gt;Take Control of Permissions in Mac OS X&lt;/a&gt;" that provides a bunch of help for the average Mac user in dealing with the often mysterious subject of "permissions" and "ownership" of files and folders in &lt;a href="http://technorati.com/tag/MacOSX" rel="tag"&gt;Mac OS X&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Permissions and ownership of files and folders are a tough subject.&lt;br /&gt;&lt;br /&gt;Part of the reason, I think, is that there isn't a really good physical-world analogy - objects in the physical world don't have&lt;span style="font-family:courier new;"&gt; -rwxr-xr-x&lt;/span&gt; attached to them, so it's a pretty alien concept - in the physical world, if you can touch it you can write on it, now maybe you &lt;span style="font-style: italic;"&gt;shouldn't&lt;/span&gt; write on it, because of laws, social custom, etc. but there are no attached permission settings, and no operating system to enforce permissions. Ownership is an easier concept for people to grasp, because of the extensive real-world analogs.&lt;br /&gt;&lt;br /&gt;Brians' eBook is a good, searchable, handy guide to dealing with these issues, and it's only ten bucks. You do not need to know, or care about Unix to benefit from his guide, and even experienced users will find stuff they didn't know - for example what "Repair Permissions" and "Ignore Ownership" actually do.&lt;br /&gt;&lt;br /&gt;If you want to really dive into learning the Unix layer of Mac OS X, and can handle a higher price-tag, and dealing with a paper book, then I recommend my book (shameless plug, I know) "&lt;a href="http://www.matisse.net/OSX/"&gt;Unix for Mac OS X Tiger&lt;/a&gt;", but to focus on just Permissions and Ownership, Brians' book is a fine place to start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112999765591677600?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112999765591677600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112999765591677600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112999765591677600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112999765591677600'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/take-control-of-permissions-in-mac-os.html' title='Take Control of Permissions in Mac OS X'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112917702398950132</id><published>2005-10-12T21:14:00.000-07:00</published><updated>2005-10-13T18:22:59.293-07:00</updated><title type='text'>How to estimate memory usage for a large hash?</title><content type='html'>I had a conversation recently about how to estimate the size of storage for hash keys when processing a huge data set.&lt;br /&gt;&lt;br /&gt;Let's say you are gonna process 100,000,000 name/value pairs and you want to estimate how much memory is needed to store the list of unique names - is there a current "best practice" for this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112917702398950132?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112917702398950132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112917702398950132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112917702398950132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112917702398950132'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/how-to-estimate-memory-usage-for-large.html' title='How to estimate memory usage for a large hash?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112917687052651864</id><published>2005-10-12T21:10:00.000-07:00</published><updated>2005-10-22T09:41:41.130-07:00</updated><title type='text'>Problems with log files and daemontools</title><content type='html'>&lt;a href="http://cr.yp.to/daemontools.html"&gt;Daemontools&lt;/a&gt; is a software suite for Unix that makes it easy to run any program or script as a daemon.&lt;br /&gt;&lt;br /&gt;I recently ran into an interesting problem with &lt;a href="http://technorati.com/tag/daemontools" rel="tag"&gt;daemontools&lt;/a&gt; - none of the STDOUT output from my daemon was showing up in the log file.&lt;br /&gt;&lt;br /&gt;It turns out that your daemon must use unbuffered STDOUT or it won't go into the log file. In my case the daemon is a Perl script so I added automatic flushing of output buffers to the script, and it works. That means I added this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$| =1;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to the Perl script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112917687052651864?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112917687052651864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112917687052651864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112917687052651864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112917687052651864'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/10/problems-with-log-files-and.html' title='Problems with log files and daemontools'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112757712127875480</id><published>2005-09-24T08:46:00.000-07:00</published><updated>2005-10-22T09:42:27.820-07:00</updated><title type='text'>Unix for Mac OS X Tiger - book released</title><content type='html'>My book "&lt;a href="http://www.matisse.net/OSX/"&gt;Unix for Mac OS X&lt;/a&gt;" is now out in a new edition, completely revised for OS X 10.4 (Tiger).&lt;br /&gt;&lt;br /&gt;This book is a very complete beginner's guide to Unix. The book assumes no prior Unix experience and yet provides more detail than any other beginning Unix book of which I am aware. In my not-so-humble-opinion the book is probably the best beginners guide to Unix on the market.&lt;br /&gt;&lt;br /&gt;The book is over 500 pages and provide great detail on the Unix layer of &lt;a href="http://technorati.com/tag/MacOSX" rel="tag"&gt;Mac OS X&lt;/a&gt; (aka Darwin.)&lt;br /&gt;&lt;br /&gt;The book teaches you how to get to the command line, to edit files using a command line editor, to deal with Unix permissions (an entire chapter on that), and so on. I'll post a table of contents in a later posting.&lt;br /&gt;&lt;br /&gt;Buying it:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321246683/"&gt;Amazon&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://www.bookpool.com/sm/0321246683"&gt;Bookpool&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://www.computerbooks.co.uk/catalog/browse.asp?template=&amp;ref=749441&amp;amp;group=0170"&gt;Computer Books (UK)&lt;/a&gt;&lt;br /&gt;  &lt;/li&gt; &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112757712127875480?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112757712127875480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112757712127875480' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112757712127875480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112757712127875480'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/09/unix-for-mac-os-x-tiger-book-released.html' title='Unix for Mac OS X Tiger - book released'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112698495603139813</id><published>2005-09-17T12:16:00.000-07:00</published><updated>2005-10-22T09:40:33.943-07:00</updated><title type='text'>Unit Testing in Perl</title><content type='html'>I've been using the &lt;a href="http://search.cpan.org/dist/Test-Unit/"&gt;Test::Unit&lt;/a&gt; module for creating unit tests and I like it.&lt;br /&gt;&lt;br /&gt;The most common &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;Perl&lt;/a&gt; module for creating &lt;a href="http://www.petdance.com/perl/automated-testing/"&gt;Unit Tests&lt;/a&gt; is probably &lt;a href="http://search.cpan.org/dist/Test-More/"&gt;Test::More&lt;/a&gt;. For me, there are two important advantages to Test::Unit&lt;br /&gt;&lt;br /&gt;1. In Test::Unit each test is actually a subroutine, so the variables etc. you create for one test are isolated from those created for other tests.&lt;br /&gt;&lt;br /&gt;2. Test::Unit automatically runs a method called setup() before each test,a nd teardown() after each test, which is useful for things like populating a test database, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112698495603139813?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112698495603139813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112698495603139813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112698495603139813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112698495603139813'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/09/unit-testing-in-perl.html' title='Unit Testing in Perl'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112506606901836429</id><published>2005-08-26T07:19:00.000-07:00</published><updated>2005-10-22T09:43:29.033-07:00</updated><title type='text'>Perl Needs Better Tools</title><content type='html'>My article on better tools for &lt;a href="http://technorati.com/tag/perl" rel="tag"&gt;Perl&lt;/a&gt; just came out on Perl.com:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.perl.com/pub/a/2005/08/25/tools.html"&gt;http://www.perl.com/pub/a/2005/08/25/tools.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I describe many of the features available in modern Integrated Development Environments (IDE) and talk about what a good Perl IDE should have.&lt;br /&gt;&lt;br /&gt;I'll be able to respond to comment there and here for the next dayt or so, then I'll be offline for over a week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112506606901836429?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112506606901836429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112506606901836429' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112506606901836429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112506606901836429'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/08/perl-needs-better-tools.html' title='Perl Needs Better Tools'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112346451804828907</id><published>2005-08-07T18:25:00.000-07:00</published><updated>2005-08-07T18:29:44.600-07:00</updated><title type='text'>Unix commands unique to Darwin/OS X</title><content type='html'>I'm in the process of finishing the revised edition of my book, "&lt;a href="http://www.matisse.net/OSX/"&gt;Unix for Mac OS X&lt;/a&gt;" to cover OS X 10.4, Tiger), and am hoping to include a list of Unix commands that appear pretty much only in Darwin/OSX. Here's a pre-release version of the list:&lt;br /&gt;&lt;a href="http://www.matisse.net/OSX/darwin_commands.html"&gt;&lt;br /&gt;http://www.matisse.net/OSX/darwin_commands.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112346451804828907?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112346451804828907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112346451804828907' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112346451804828907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112346451804828907'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/08/unix-commands-unique-to-darwinos-x.html' title='Unix commands unique to Darwin/OS X'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112344226395959236</id><published>2005-08-07T12:15:00.000-07:00</published><updated>2005-08-07T18:29:01.593-07:00</updated><title type='text'>Dispatches from Blogistan - a travel guide in the making.http://www.blogger.com/img/gl.link.gif</title><content type='html'>Long-time friend Suzanne Stefanac is &lt;a href="http://www.dispatchesfromblogistan.com/"&gt;on the case at http://www.dispatchesfromblogistan.com/ creating a new book for Peachpit Press&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Given Suzanne's experience with media and facility with people, this should be a friendly, intelligent and insightful work. I hear she is going to include a chapter on Good Writing, something we could all use some help with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112344226395959236?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112344226395959236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112344226395959236' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112344226395959236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112344226395959236'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/08/dispatches-from-blogistan-travel-guide.html' title='Dispatches from Blogistan - a travel guide in the making.http://www.blogger.com/img/gl.link.gif'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112295498169929765</id><published>2005-08-01T20:54:00.000-07:00</published><updated>2005-08-01T20:56:38.180-07:00</updated><title type='text'>Ruby-on-Rails looking interesting</title><content type='html'>OK, I admit the momentum is getting to me.&lt;br /&gt;I started looking into Ruby several years ago, but never built anything with it.&lt;br /&gt;&lt;br /&gt;Now, thing like &lt;a href="http://lesscode.org/2005/07/15/more-j2ee-vs-rails/"&gt;this post showing how little code can be needed&lt;/a&gt; are making me itch to try again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112295498169929765?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112295498169929765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112295498169929765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112295498169929765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112295498169929765'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/08/ruby-on-rails-looking-interesting.html' title='Ruby-on-Rails looking interesting'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112287538546674195</id><published>2005-07-31T22:48:00.000-07:00</published><updated>2005-07-31T22:49:45.466-07:00</updated><title type='text'>Progress on Perl tools Article</title><content type='html'>I finally finished a complete first draft of my article for Perl.com on better development tools for Perl. It's been sent off to chromatic at O'Reilly and hopefully I'll hear back soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112287538546674195?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112287538546674195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112287538546674195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112287538546674195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112287538546674195'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/07/progress-on-perl-tools-article.html' title='Progress on Perl tools Article'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112282652088028809</id><published>2005-07-31T09:07:00.000-07:00</published><updated>2005-07-31T09:15:35.040-07:00</updated><title type='text'>VIP - New Perl Editor Project</title><content type='html'>&lt;a href="http://search.cpan.org/%7Ekaare/"&gt;Kaare Rasmussen&lt;/a&gt; told me about a new CPAN project led by &lt;a href="http://search.cpan.org/%7Enkh/"&gt;Nadim Ibn Hamouda El Khemir&lt;/a&gt; called VIP:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;The goal of the VIP project is to produce a first class Perl editor that&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;can be used as a component in a (yet to be developed) IDE. We will try&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;to write vip so it will build on the strong points of of Perl 5 and 6.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;Our first step is to provide the editor itself. It will consist of the&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;core engine and have (at first) three interfaces; used from Perl itself,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;a text based (curses) and a graphic (gtk) interface.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;Apart from the usual features, such as syntax coloring and&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;templates/wizards, we plan to include innovative features, like support&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;for Pair Programming, and to make it extremely configurable and&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;pluggable (integration with Sprog (http://sprog.sourceforge.net/) will&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;be one way to extend Vip).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;The project is currently in the initial phase and we expect to have a&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;working draft within the next couple of months.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;We can always use help. To test it out, find bugs, propose features and&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;write documentation, plugins and code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;The project has a name on CPAN:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;&lt;a href="http://search.cpan.org/%7Enkh/Text-Editor-Vip-0.011/"&gt;http://search.cpan.org/~nkh/Text-Editor-Vip-0.011/,&lt;/a&gt; a home page&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;(http://...) and a discussion forum (http://www.cpanforum.org/...).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.technorati.com/tag/Perl" rel="tag"&gt;Perl&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.technorati.com/tag/IDE" rel="tag"&gt;IDE&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112282652088028809?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112282652088028809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112282652088028809' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112282652088028809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112282652088028809'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/07/vip-new-perl-editor-project.html' title='VIP - New Perl Editor Project'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112282497655908672</id><published>2005-07-31T08:48:00.000-07:00</published><updated>2005-07-31T09:05:42.920-07:00</updated><title type='text'>Problem installing MySQL 4.1.13 on Mac OS X 10.4.2</title><content type='html'>Bug report filed with &lt;a href="http://www.technorati.com/tag/mysql" target="_blank" rel="tag"&gt;MySQL&lt;/a&gt;: &lt;a href="http://bugs.mysql.com/bug.php?id=12288"&gt;http://bugs.mysql.com/bug.php?id=12288&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the bug description:&lt;br /&gt;&lt;pre class="note"&gt;Trying to compile MySQL 4.1.13 on &lt;a href="http://www.technorati.com/tag/macosx" rel="tag" target="_blank"&gt;Mac OS X&lt;/a&gt; 10.4.2&lt;br /&gt;gcc_select show gcc 4.0.0:&lt;br /&gt;$ gcc_select&lt;br /&gt;Current default compiler:&lt;br /&gt;gcc version 4.0.0 20041026 (Apple Computer, Inc. build 4061)&lt;br /&gt;&lt;br /&gt;$ locate gcc_s&lt;br /&gt;/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libgcc_s.dylib&lt;br /&gt;/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libgcc_static.a&lt;br /&gt;/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libgcc_s_ppc64.dylib&lt;br /&gt;/usr/sbin/gcc_select&lt;br /&gt;/usr/share/man/man8/gcc_select.8&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The build fails with:&lt;br /&gt;...&lt;br /&gt;Making all in sql&lt;br /&gt;if g++ -DMYSQL_SERVER -DDEFAULT_MYSQL_HOME="\"/usr/local/mysql\""&lt;br /&gt;-DDATADIR="\"/usr/local/mysql/var\""&lt;br /&gt;-DSHAREDIR="\"/usr/local/mysql/share/mysql\"" -DHAVE_CONFIG_H -I. -I. -I..&lt;br /&gt;-I../innobase/include -I../include -I../include -I../regex -I.     -O3&lt;br /&gt;-DDBUG_OFF    -fno-implicit-templates -fno-exceptions -fno-rtti&lt;br /&gt;-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE&lt;br /&gt;-DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT -MT gen_lex_hash.o -MD -MP -MF&lt;br /&gt;".deps/gen_lex_hash.Tpo" -c -o gen_lex_hash.o gen_lex_hash.cc; then mv -f ".deps/gen_lex_hash.Tpo" ".deps/gen_lex_hash.Po"; else rm -f&lt;br /&gt;".deps/gen_lex_hash.Tpo"; exit 1; fi&lt;br /&gt;/bin/sh ../libtool --preserve-dup-deps --mode=link g++  -O3 -DDBUG_OFF&lt;br /&gt;-fno-implicit-templates -fno-exceptions -fno-rtti -DHAVE_DARWIN_THREADS&lt;br /&gt;-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ&lt;br /&gt;-DIGNORE_SIGHUP_SIGQUIT   -o gen_lex_hash  gen_lex_hash.o ../myisam/libmyisam.a&lt;br /&gt;../myisammrg/libmyisammrg.a ../heap/libheap.a ../vio/libvio.a&lt;br /&gt;../mysys/libmysys.a ../dbug/libdbug.a ../regex/libregex.a&lt;br /&gt;../strings/libmystrings.a -lz   -lm&lt;br /&gt;mkdir .libs&lt;br /&gt;g++ -O3 -DDBUG_OFF -fno-implicit-templates -fno-exceptions -fno-rtti&lt;br /&gt;-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE&lt;br /&gt;-DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT -o gen_lex_hash gen_lex_hash.o&lt;br /&gt;-Wl,-bind_at_load  ../myisam/libmyisam.a ../myisammrg/libmyisammrg.a&lt;br /&gt;../heap/libheap.a ../vio/libvio.a ../mysys/libmysys.a ../dbug/libdbug.a&lt;br /&gt;../regex/libregex.a ../strings/libmystrings.a -lz -lm&lt;br /&gt;/usr/bin/ld: can't locate file for: -lgcc_s&lt;br /&gt;collect2: ld returned 1 exit status&lt;br /&gt;make[2]: *** [gen_lex_hash] Error 1&lt;br /&gt;make[1]: *** [all-recursive] Error 1&lt;br /&gt;make: *** [all] Error 2&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How to repeat:&lt;/strong&gt;&lt;br /&gt;Use source distribution mysql-4.1.13.tar.gz&lt;br /&gt;&lt;br /&gt;$ tar xfvz mysql-4.1.13.tar.gz&lt;br /&gt;$ cd mysql-4.1.13&lt;br /&gt;$ ./configure --prefix=/usr/local/mysql&lt;br /&gt;$ make&lt;br /&gt;&lt;br /&gt;Build fails.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Suggested fix:&lt;/strong&gt;&lt;br /&gt;None known yet.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://technorati.com/tag/mysql macosx" rel="tag"&gt;mysql macosx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112282497655908672?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112282497655908672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112282497655908672' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112282497655908672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112282497655908672'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/07/problem-installing-mysql-4113-on-mac.html' title='Problem installing MySQL 4.1.13 on Mac OS X 10.4.2'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112109842754986086</id><published>2005-07-11T09:11:00.000-07:00</published><updated>2005-07-11T09:13:47.553-07:00</updated><title type='text'>Access Control Lists (ACLs) in Mac OS X</title><content type='html'>Powerful but complex, and hard to understand.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;chmod +a "dancers allow list,directory_inherit" dropbox&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;should allow anyone in group &lt;span style="font-family: courier new;"&gt;dancers&lt;/span&gt; to list the contents of &lt;span style="font-family: courier new;"&gt;dropbox&lt;/span&gt; and any subdirectories, but the inheritence doesn't seem to happen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112109842754986086?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112109842754986086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112109842754986086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112109842754986086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112109842754986086'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/07/access-control-lists-acls-in-mac-os-x.html' title='Access Control Lists (ACLs) in Mac OS X'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-112093292333092301</id><published>2005-07-09T11:14:00.000-07:00</published><updated>2005-07-09T11:16:37.670-07:00</updated><title type='text'>New refactoring book in the works?</title><content type='html'>I heard from a reliable source yesterday that O'Reilly is considering doing a book on Refactoring. Maybe they'll include Perl in it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-112093292333092301?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/112093292333092301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=112093292333092301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112093292333092301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/112093292333092301'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/07/new-refactoring-book-in-works.html' title='New refactoring book in the works?'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-111976677014841014</id><published>2005-06-25T23:14:00.000-07:00</published><updated>2005-06-25T23:19:30.150-07:00</updated><title type='text'>Perl IDE's</title><content type='html'>Two of the most sophisticated graphical Integrated Development Environments (IDE) for Perl are probably &lt;a href="http://e-p-i-c.sf.net/"&gt;EPIC&lt;/a&gt; and &lt;a href="http://www.activestate.com/Products/Komodo/"&gt;Komodo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Two command-line IDE's are &lt;code&gt;emacs&lt;/code&gt; and &lt;code&gt;vi/vim&lt;/code&gt;. There are a variety of extensions that people have created for these two venerable text editors that provide many of the capabilities of graphical IDE's.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-111976677014841014?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/111976677014841014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=111976677014841014' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/111976677014841014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/111976677014841014'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/06/perl-ides.html' title='Perl IDE&apos;s'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13964332.post-111976552989880533</id><published>2005-06-25T22:53:00.000-07:00</published><updated>2005-06-25T22:58:49.900-07:00</updated><title type='text'>Better Development Tools for Perl, or Perl is Dead</title><content type='html'>I'm working on an article for &lt;a href="http://perl.com/"&gt;O'Reilly's perl.com&lt;/a&gt; wherein I assert that what Perl needs is few great Integrated Development Environments that equal or exceed the features currently available for Java.&lt;br /&gt;&lt;br /&gt;An early rough set of notes on the subject is online at &lt;a href="http://www.eigenstate.net/perl_tools/"&gt;http://www.eigenstate.net/perl_tools/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The fully developed article should be on &lt;a href="http://perl.com/"&gt;perl.com&lt;/a&gt; in a month or two.&lt;br /&gt;&lt;br /&gt;A related an valuable article is &lt;a href="http://www.perl.com/pub/a/2005/06/09/ppi.html"&gt;Adam Kennedy's article on his new PPI module&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13964332-111976552989880533?l=twoalpha.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://twoalpha.blogspot.com/feeds/111976552989880533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13964332&amp;postID=111976552989880533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/111976552989880533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13964332/posts/default/111976552989880533'/><link rel='alternate' type='text/html' href='http://twoalpha.blogspot.com/2005/06/better-development-tools-for-perl-or.html' title='Better Development Tools for Perl, or Perl is Dead'/><author><name>Matisse Enzer</name><uri>http://www.blogger.com/profile/03736762585596345292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_5K3JHFbzanQ/SbP2cpZKv5I/AAAAAAAAABE/vYil35zrDvE/S220/matisse_firenze_headshot_small.png'/></author><thr:total>0</thr:total></entry></feed>
