<?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-1095111220804824515</id><updated>2012-02-13T00:44:32.114-08:00</updated><category term='UNIX'/><category term='Weird dreams'/><category term='MVC'/><category term='Standards'/><category term='tablet'/><category term='pith'/><category term='Windows'/><category term='Tutorial'/><category term='Autocatalysis'/><category term='Green Economy'/><category term='Programming'/><category term='Testing'/><category term='Synecdoche'/><category term='Node.js'/><category term='Criticism'/><category term='Web Design'/><category term='Programming by Side-Effect'/><category term='Git'/><category term='Autopoietic Systems'/><category term='EV'/><category term='Universal Design'/><category term='Graceful Degradation'/><category term='Health'/><category term='Social Networking'/><category term='slate'/><category term='business'/><category term='Human Condition'/><category term='CSS'/><category term='REST'/><category term='Javascript'/><category term='pandigital'/><category term='Progressive Enhancement'/><category term='Rails'/><category term='Ruby On Rails'/><category term='XML'/><category term='OSX'/><category term='PHP'/><category term='Science-Technology-Engineering-Math (STEM)'/><category term='android'/><category term='Crowd Sourcing'/><category term='Joomla'/><category term='Web Architecture'/><category term='Diesel'/><category term='Content Management'/><category term='Hobo'/><category term='Ruby'/><category term='Django'/><category term='Sustainability'/><category term='quotes'/><category term='Process'/><category term='iPad'/><category term='Education'/><title type='text'>Unity is Plural</title><subtitle type='html'>Thoughts on technology and life, objective reality and individualism, in opposition to marketing spin and the false hope of change for change's sake.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.unityisplural.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default?start-index=101&amp;max-results=100'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>240</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6150093404422870245</id><published>2012-02-08T16:05:00.000-08:00</published><updated>2012-02-08T16:05:39.319-08:00</updated><title type='text'>Install Git under Windows</title><content type='html'>&lt;br /&gt;&lt;b&gt;Install Git&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;Windows installer &lt;a href="http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.8-preview20111206.exe&amp;amp;can=3&amp;amp;q="&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Under Windows, use the Bash Shell or GUI app.&lt;br /&gt;You can also fetch TortoiseGIT to work with the Windows gui environment.&lt;br /&gt;&lt;br /&gt;Menu -&amp;gt; Git -&amp;gt; Git Bash&lt;br /&gt;&lt;br /&gt;You will see:&lt;br /&gt;Welcome to Git (version 1.7.8-preview20111206)&lt;br /&gt;&lt;br /&gt;Run 'git help git' to display the help index.&lt;br /&gt;Run 'git help &amp;lt;command&amp;gt;' to display help for specific commands.&lt;br /&gt;$&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set up a proper workspace&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Please translate the username (whome) and pathnames as appropriate.&lt;br /&gt;&lt;br /&gt;$ pwd&lt;br /&gt;/c/Documents and Settings/whome&lt;br /&gt;&lt;br /&gt;$ mkdir workspace&lt;br /&gt;$ cd workspace&lt;br /&gt;&lt;br /&gt;$ git config --global user.name "Who Me"&lt;br /&gt;$ git config --global user.email "whome@some.domain.com"&lt;br /&gt;&lt;br /&gt;$ git clone &amp;nbsp;some.repo.url/reponame.git&lt;br /&gt;&lt;br /&gt;Cloning into 'reponame'...&lt;br /&gt;done.&lt;br /&gt;&lt;br /&gt;At this point, you'll have a working local git repo that can be pulled from the remote repo, and pushed (assuming the repo url allows write access). &lt;br /&gt;&lt;br /&gt;More cheat sheets for git can be found here:&lt;br /&gt;&lt;a href="http://help.github.com/git-cheat-sheets/"&gt;http://help.github.com/git-cheat-sheets/&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/1095111220804824515-6150093404422870245?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6150093404422870245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6150093404422870245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6150093404422870245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6150093404422870245'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/02/install-git-under-windows.html' title='Install Git under Windows'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8394453616423982903</id><published>2012-01-27T21:08:00.000-08:00</published><updated>2012-01-27T21:08:44.171-08:00</updated><title type='text'>Why we should care about server side JavaScript</title><content type='html'>A software practitioner recently asked me what are the benefits of a functional language, and why would one want to use, say, JavaScript for an MVC Web application stack. A stack to consider would be&amp;nbsp;Ruby on Rails for instance. Clearly, developers in the Node.js community have their eyes set on that problem space.&lt;br /&gt;&lt;br /&gt;I wasn't prepared answer his question, at least not adequately.&lt;br /&gt;&lt;br /&gt;JavaScript certainly offers interesting things like closures and anonymous functions, which make event-driven programming interesting.&amp;nbsp;&amp;nbsp;Closures, my friend pointed out, are like deep class&amp;nbsp;hierarchies in an OO system, and can obscure the flow of control. It is true that closures come at a cost, but there are benefits as well in the reduction of code and less time spent in allocating temporary variables and in avoidance of copying. But closures are just one construct among several primitives in functional programming that work together to form an extensible system of logic. A grammar, if you will.&lt;br /&gt;&lt;br /&gt;Why should we care?&lt;br /&gt;&lt;br /&gt;Improved engines, especially Google's V8, have brought speed characteristics to rival that of C++. If JavaScript were still as slow and memory intensive as, say, Java, it might have survived in the browser space. Yet V8 brings JavaScript benchmarks into the same order of magnitude as statically compiled languages. It still isn't as fast as C or Perl5, but it is on-par with PHP and C++ and edges out Ruby (sorry Ruby, I do love you, but you're not quite as fast as V8). That is one characteristic that has some Web app developers all hot and bothered about Node.js.&lt;br /&gt;&lt;br /&gt;And for whatever faults it has, JavaScript has less cruft than PHP, C++, or Java. Functional primitives combined with a kind of Lamarkian inheritance and minimal data types make it a very cohesive language despite its half-baked flaws. It doesn't have classes, but then again, &lt;i&gt;it doesn't have classes&lt;/i&gt;. JavaScript does have prototypal inheritance.&amp;nbsp;Modules and packages have much more practical benefit, and you can make those in JavaScript. &amp;nbsp;With cleaned up syntaxes such as that offered by CoffeeScript, some of the worst flaws can be entirely elided from the coding experience while making programs even shorter.&lt;br /&gt;&lt;br /&gt;As a language, JavaScript leaves some things to be desired. The lack of tail-call optimization, while generally treated as YAGNI, prohibits some interesting implementation techniques. The widely used long-running script detection makes sense for browsers and servers, but for background processing tasks and monitoring not so much.&amp;nbsp;There are some interesting ways of managing blocks of code, formulating methods, and handling control flow in Ruby and Python that I sometimes wish were in JavaScript. &amp;nbsp;The weirdness of falsiness and truthiness and == is eye-rollingly campy.&lt;br /&gt;&lt;br /&gt;But in spite of its flaws, JavaScript is still a much saner language than Java and unlike Java/Ruby/Python/C++/Perl/PHP/whatever, it is part of almost every Web browser.&amp;nbsp;Node opened up the path to a coding experience in which the seams between deployment environments are much cleaner and tighter, allowing them to be increasingly well-defined, well-factored, well-integrated, and well-tested with less code.&lt;br /&gt;&lt;br /&gt;As a spiritual descendant of Scheme it is difficult to stay mad at JavaScript for very long even when the browser environment makes simple tasks&amp;nbsp;grueling; eventually the elegance and simplicity of the language still draws you in.&lt;br /&gt;&lt;br /&gt;Approachable beauty intrinsically engenders creativity and productivity.&amp;nbsp;That in a nutshell, in my very humble and only poorly-informed opinion, is why programmers are noticing JavaScript.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8394453616423982903?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8394453616423982903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8394453616423982903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8394453616423982903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8394453616423982903'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/why-we-should-care-about-server-side.html' title='Why we should care about server side JavaScript'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7813426083524819233</id><published>2012-01-26T21:19:00.000-08:00</published><updated>2012-01-26T21:19:56.598-08:00</updated><title type='text'>Class Variables versus Class Instance Variables in Ruby</title><content type='html'>I'm going to do a code dump and annotate.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/usr/bin/env ruby&lt;br /&gt;&lt;br /&gt;class Something&lt;br /&gt;&amp;nbsp; @@class_variable = 0&lt;br /&gt;&lt;br /&gt;&amp;nbsp; def initialize( name )&lt;br /&gt;&amp;nbsp; &amp;nbsp; @@class_variable += 1&lt;br /&gt;&amp;nbsp; &amp;nbsp; @name = name&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;&amp;nbsp; def value&lt;br /&gt;&amp;nbsp; &amp;nbsp; "#{@name},#{@@class_variable}"&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class SomethingElse &amp;lt; Something&lt;br /&gt;&amp;nbsp; def initialize( name )&lt;br /&gt;&amp;nbsp; &amp;nbsp; super(name)&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;joe = Something.new("Joe")&lt;br /&gt;puts "Joe = #{joe.value}"&lt;br /&gt;mary = Something.new("Mary")&lt;br /&gt;puts "Mary = #{mary.value}"&lt;br /&gt;sam = SomethingElse.new("Sam")&lt;br /&gt;puts "Sam = #{sam.value}"&lt;br /&gt;puts "Finished creating. Now Joe = #{joe.value}, Mary = #{mary.value}, and Sam = #{sam.value}"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Class variables are shared among all subclasses.&lt;/i&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class SomethingEntirelyDifferent &amp;lt; SomethingElse&lt;br /&gt;&amp;nbsp; @@class_variable = 0&lt;br /&gt;&amp;nbsp; def initialize( name )&lt;br /&gt;&amp;nbsp; &amp;nbsp; super(name)&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts&lt;br /&gt;ferdinand = SomethingEntirelyDifferent.new("Ferdinand")&lt;br /&gt;puts "Ferdinand = #{ferdinand.value}"&lt;br /&gt;puts "Created subclass with same classvariable. Now Joe = #{joe.value}, Mary = #{mary.value}, and Sam = #{sam.value}"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Class variables are not shadowed. They are scoped wrt the inheritance chain.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Class variables are candidates for unintentional side-effects.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;class SomethingAgain &amp;lt; SomethingElse&lt;br /&gt;&amp;nbsp; @class_instance_variable = 0&lt;br /&gt;&lt;br /&gt;&amp;nbsp; class &amp;lt;&amp;lt; self; attr_accessor :class_instance_variable end&lt;br /&gt;&lt;br /&gt;&amp;nbsp; attr_accessor :instance_variable&lt;br /&gt;&lt;br /&gt;&amp;nbsp; def initialize( name )&lt;br /&gt;&amp;nbsp; &amp;nbsp; self.class.class_instance_variable += 1&lt;br /&gt;&amp;nbsp; &amp;nbsp; super(name)&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;albert = SomethingAgain.new("Albert")&lt;br /&gt;puts "Albert = #{albert.value}"&lt;br /&gt;puts "Albert's class = #{albert.class.name} &amp;amp;&amp;amp; class instance = #{albert.class.class_instance_variable}"&lt;br /&gt;jane = SomethingAgain.new("Jane")&lt;br /&gt;puts "Created subclass with class instance variable, and two instances."&lt;br /&gt;puts "Jane's class = #{jane.class.name} &amp;amp;&amp;amp; class instance = #{jane.class.class_instance_variable}"&lt;br /&gt;puts "Albert's class = #{albert.class.name} &amp;amp;&amp;amp; class instance = #{albert.class.class_instance_variable}"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Class instance variables are attached to an object's class object.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;class SomethingMore &amp;lt; SomethingAgain&lt;br /&gt;&amp;nbsp; @class_instance_variable = 1138&lt;br /&gt;&amp;nbsp; def initialize( name)&lt;br /&gt;&amp;nbsp; &amp;nbsp; super(name)&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;mike = SomethingMore.new("Mike")&lt;br /&gt;puts "Mike = #{mike.value}"&lt;br /&gt;puts "Mike's class = #{mike.class.name} &amp;amp;&amp;amp; class instance = #{mike.class.class_instance_variable}"&lt;br /&gt;puts "Created subclass of class with class instance variable, with its own class instance variable"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Class instance variables aren't visible to subclasses.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Class instance variables are required on subclasses when base-class methods that read or write them.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;puts "Albert's class = #{albert.class.name} &amp;amp;&amp;amp; class instance = #{albert.class.class_instance_variable}"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Class instance variables are not visible to other subclasses in the inheritance chain.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;All in all, the @@class variables encourage collusive coding and appear to carry a high risk of causing race conditions and other unintentional side-effects. The @class instance variables carry a somewhat lesser risk. Barring some obscure trick, a class instance variable is always associated with precisely one class. But even with class instance variables, multiple object instances can gain access to the variable through their own "class" property, with the potential for unintended side-effects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7813426083524819233?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7813426083524819233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7813426083524819233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7813426083524819233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7813426083524819233'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/class-variables-versus-class-instance.html' title='Class Variables versus Class Instance Variables in Ruby'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2334834669168352254</id><published>2012-01-25T19:54:00.000-08:00</published><updated>2012-01-26T08:01:44.851-08:00</updated><title type='text'>Simpler than possible</title><content type='html'>&lt;blockquote&gt;A scientific theory should be as simple as possible, but no simpler&lt;/blockquote&gt;&lt;div style="text-align: center;"&gt;- A. Einstein&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;I'm not sure of the precise context of Einstein's words, but it seemed to do with deflection of criticisms toward one of the relativity theories.&lt;br /&gt;&lt;br /&gt;A kid with a magnifying glass intuitively understands the meaning: the focal length of the lens being a theory, too close in or too far away both give rise to fuzzy representations that aren't too bright.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/8/8f/Focal-length.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/8/8f/Focal-length.png" width="106" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;By DrBob via Wikimedia Commons&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The question is one of focus. Literally, not figuratively.&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Considering that vision originates in the brain and its purpose is to create a predictive theory of the world around us, it is unremarkable that lenses are incorporated into our biology. The lens reduces the scale of the external &lt;strike&gt;problem&lt;/strike&gt; visual field while concentrating signals in the process, and makes a projection onto a concavely curved surface covered with photoreceptors. The lens is an image transfer device.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The brain then, is a device onto which images are transferred. Into, onto, it is hard to express: the memories modify the fine grained structure of neural dendrites, which incorporate the sensory inputs in analog gradients, and do so more or less as a whole.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I propose an idea of Focal Distance and the degree of Focal Alignment when considering how fit a software language, idiom, framework, system, or platform is to a particular &lt;strike&gt;purpose&lt;/strike&gt; set of stakeholder needs.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This assumes that the needs are in some manner, self-consistent -- they lie along a parallel trajectory.&amp;nbsp;It may be that due to conflicting interests between stakeholders, the solutions deemed acceptable will never, ever, approach Focal Alignment. There could be orthogonal components to the needs, causing the lens -- and by extension the solution-image -- to skew. There could be absolute differences in stakeholder positions along the same trajectory&amp;nbsp;or orientation in opposite directions along the same trajectory, giving a compromised Focal Distance and solutions that are blurry.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2334834669168352254?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2334834669168352254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2334834669168352254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2334834669168352254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2334834669168352254'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/simpler-than-possible.html' title='Simpler than possible'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-261675069473297297</id><published>2012-01-19T07:57:00.000-08:00</published><updated>2012-01-19T08:22:37.062-08:00</updated><title type='text'>What Windows POSIX Compliance Teaches Us: a Wink and a Nod</title><content type='html'>&lt;br /&gt;&lt;div class="p1"&gt;Many years ago, the Federal government put out a series of requirements, the FIPS standards.&amp;nbsp;IIRC, the POSIX specs are part of FIPS. &amp;nbsp;To generalize, Linux is an implementation of POSIX.&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;POSIX was pushed because of a few factors:&lt;/div&gt;&lt;div class="p2"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;vendors' operating systems are divergent, making it harder to migrate programs between systems&lt;/li&gt;&lt;li&gt;vendors go out of business, shut down product lines, and make radical changes to them, so development using their APIs are an unsound investment over time&lt;/li&gt;&lt;li&gt;government institutions have to carry the burden of systems they buy into for decades&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="p2"&gt;FIPS are procurement standards. This means that in order to sell a computer solution to the Federal government, a vendor must satisfy the POSIX requirements. The intent is clear: to safeguard public investments. An improper balance of power in the hands of a supplier inevitably leads to deleterious actions against consumers. POSIX has the effect of making investors out of consumers. &amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;What happened afterward is a travesty: Microsoft Windows/DOS based PC clones had picked up steam in the consumer market, and NT was being aimed at enterprises including government. Microsoft gave&amp;nbsp;NT a partial POSIX subsystem, which just about nobody used, to get a rubber-stamp for sale into government accounts. A panel of judges gave the nod, and forced the Coast Guard to accept Windows based proposals in &lt;a href="http://web.archive.org/web/20020212030701/www.opengroup.org/procurement/s_walli.htm"&gt;a 1995 case&lt;/a&gt;.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;Apparently, the NT POSIX subsystem has been replaced a few times, and was crippled from the start.&amp;nbsp;That's why everyone and their brother uses Cygwin, UnixUtils, or MinGW for porting Unix apps to Windows. But due to Windows' non-compliance, it doesn't run Unix style applications all that well.&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-OkQBCQvxZBg/Txg8nVkbqsI/AAAAAAAAAGg/Mc6agstSoqI/s1600/flickr-3118644967-original.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="367" src="http://3.bp.blogspot.com/-OkQBCQvxZBg/Txg8nVkbqsI/AAAAAAAAAGg/Mc6agstSoqI/s400/flickr-3118644967-original.jpg" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;credit: Zombie classified by bloodredrapture on Flickr&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div class="p2"&gt;Microsoft only added the DOA POSIX subsystem so they could claim compliance, when their compliance was a sham on its face. The subsystem was virtually a zombie interface. &amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;The Coast Guard lawyers in the 1995 case would have done well to ask a multilingual colleague to assist, using a deliberately broken grammar in a non-English language to present some portion of their argument. Prior to being cited for contempt, they could then argue that their compliance with requirements for language interfaces in court was similar in kind to NT's conformance to POSIX interface requirements, and with identical outcomes.&amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;Government purchases of closed systems like Microsoft Windows amount to a collusion with vendors in &amp;nbsp;&lt;i&gt;constructive non-compliance&lt;/i&gt;: apparently in conformance but with precisely the opposite effects as those intended by the standards authors. Such is the power of the judiciary to rewrite law.&amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="p1"&gt;One way to re-approach the original intent of FIPS is to reformulate compliance in terms of public trusts, or something akin to a credit union in which software is the primary asset. We have very good institutional precedents in the form of non-profit organizations, like the Apache Software Foundation and the Mozilla Foundation. (Indeed, these two alone account for &amp;nbsp;a huge amount of the Web infrastructure that drives our economy.)&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;For software to be purchased by a government entity its assets and its dependencies should be escrowed in the public trust, largely if not completely. In the case of open source software using distributed version control services, this could be accomplished easily: just identify yourself and the repositories. Private concerns would have to accept that the public's interest in not losing access to the intellectual property outweighs their interest in keeping it private, and trust the escrow service to not leak their IP prematurely; or chose to not play in the public space.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;Those institutions that adopt closed systems learly get immediate and substantive benefits, particularly in the predictability of the user interface, and plug-and-play commodity peripherals. &amp;nbsp;Those same institutions are also now bumping up against the long-term consequences of adopting a strategy of developing for privately held operating systems. A nod is as good as a wink to a blind horse.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-261675069473297297?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/261675069473297297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=261675069473297297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/261675069473297297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/261675069473297297'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/windows-posix-compliance-wink-and-nod.html' title='What Windows POSIX Compliance Teaches Us: a Wink and a Nod'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-OkQBCQvxZBg/Txg8nVkbqsI/AAAAAAAAAGg/Mc6agstSoqI/s72-c/flickr-3118644967-original.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-819120233151159071</id><published>2012-01-16T15:08:00.000-08:00</published><updated>2012-01-16T15:08:33.883-08:00</updated><title type='text'>Compass imports</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Yeah, some articles on this blog are a dumping ground for when a crib is needed.&lt;br /&gt;The Compass docs are not particularly easy to scan through quickly.&lt;br /&gt;&lt;br /&gt;Compass imports&lt;br /&gt;ex: @import "compass/layout"&lt;br /&gt;&lt;br /&gt;&lt;div id="boxes"&gt;compass/&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; grid-background&lt;br /&gt;&amp;nbsp; sticky-footer&lt;br /&gt;&amp;nbsp; stretching&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; css3&lt;br /&gt;&amp;nbsp; &amp;nbsp; appearance – Specify the CSS3 appearance property.&lt;br /&gt;&amp;nbsp; &amp;nbsp; background clip – Specify the background clip for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; background origin – Specify the background origin for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; background size – Specify the background size for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; border radius – Specify the border radius for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; box – This module provides mixins that pertain to the CSS3 Flexible Box.&lt;br /&gt;&amp;nbsp; &amp;nbsp; box shadow – Specify the box shadow for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; box sizing – Specify the box sizing for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; columns – Specify a columnar layout for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; font face – Specify a downloadable font face for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; gradient – Specify linear gradients and radial gradients for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; images – Specify linear gradients and radial gradients for many browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; inline block – Declare an element inline block for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; opacity – Specify the opacity for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; text shadow – Specify the text shadow for all browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; transform – Specify transformations for many browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; transition – Specify a style transition for all browsers.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; typography&lt;br /&gt;&amp;nbsp; &amp;nbsp; links&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; hover-link&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; link-colors&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; unstyled-link&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; lists&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; bullets&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; horizontal-list&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bullets&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; clearfix&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; float&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; inline-block-list&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bullets&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; inline-block&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; float&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; horizontal-list&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; inline-list&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; text&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ellipsis&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; force-wrap&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; no-wrap&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; text-replacement&lt;/div&gt;&amp;nbsp; &amp;nbsp; vertical-rhythm&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; utilities&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; links – Tools for styling anchor links. (from typography)&lt;br /&gt;&amp;nbsp; &amp;nbsp; lists – Tools for styling lists. (from typography)&lt;br /&gt;&amp;nbsp; &amp;nbsp; text – Style helpers for your text. (from typography)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; color – Utilities for working with colors.&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;color-contrast&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; general – Generally useful utilities that don't fit elsewhere.&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Clearfix – Mixins for clearfixing.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Float – Mixins for cross-browser floats.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Hacks – Mixins for hacking specific browsers.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Minimums – Mixins for cross-browser min-height and min-width.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Reset – Mixins for resetting elements (old import).&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Tag Cloud – Mixin for styling tag clouds.&lt;/div&gt;&amp;nbsp; &amp;nbsp; sprites – Sprite mixins.&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; sprite-image&lt;/div&gt;&amp;nbsp; &amp;nbsp; tables – Style helpers for your tables.&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; table-striping&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; table-borders&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; table-scaffolding&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;#boxes div { border-top: solid thin grey; border-left: solid thin grey; margin-left: 1em; }&lt;/style&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-819120233151159071?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/819120233151159071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=819120233151159071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/819120233151159071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/819120233151159071'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/compass-imports.html' title='Compass imports'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2373121402506204981</id><published>2012-01-16T09:26:00.000-08:00</published><updated>2012-01-16T09:26:09.275-08:00</updated><title type='text'>Closure as a property of a package management system</title><content type='html'>I filed a bug today for a simple OSX Homebrew recipe for git-hg. Basically, git-hg allows you to clone and work with mercurial repositories using a git repo. &amp;nbsp;Upon installing the recipe though, cloning resulted in an empty directory, and a fetch (performed out of curiosity) got:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "/usr/local/Cellar/git-hg/HEAD/bin/../fast-export/hg-fast-export.py", line 6, in &amp;lt;module&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; from mercurial import repo,hg,cmdutil,util,ui,revlog,node&lt;br /&gt;ImportError: No module named mercurial&lt;br /&gt;&lt;br /&gt;Aha, so the immediate problem is that the Python mercurial module is missing.&lt;br /&gt;&lt;br /&gt;The actual problem is a little more pervasive: the git-hg recipe didn't close over all of its environmental settings and software dependencies.&lt;br /&gt;&lt;br /&gt;A further example of faulty closures was seen in the associated Python install. &amp;nbsp;Why was the module missing? &amp;nbsp;The first place to look is the Python distribution's site-packages folder (&amp;nbsp;/usr/local/lib/python2.7/site-packages for the Homebrew example).&lt;br /&gt;&lt;br /&gt;This turned out to be a puzzler because OSX also comes with an older version of Python installed. Thus, as the &lt;a href="https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CCMQFjAA&amp;amp;url=https%3A%2F%2Fgithub.com%2Fmxcl%2Fhomebrew%2Fwiki%2FHomebrew-and-Python&amp;amp;ei=11wUT-71DIi3twf2hMisAg&amp;amp;usg=AFQjCNExluBFTnCjKPs47mcFwZe0ktHuFQ"&gt;Homebrew and Python&lt;/a&gt; page explains, you have some fiddling to do with your PATH and PYTHONPATH environmental settings. &amp;nbsp; While one cannot predict or completely automate environmental dependencies, it would have been very nice to be reminded of the potential conflict by the Python recipe.&lt;br /&gt;&lt;br /&gt;The omission constitutes a lack of closure of the recipe over its dependencies.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2373121402506204981?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2373121402506204981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2373121402506204981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2373121402506204981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2373121402506204981'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/closure-as-property-of-package.html' title='Closure as a property of a package management system'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6549965850481607898</id><published>2012-01-15T21:19:00.000-08:00</published><updated>2012-01-15T21:19:30.503-08:00</updated><title type='text'>JavaScript is Dead. Long Live JavaScript</title><content type='html'>OK, this is going to be light on fact and heavy on impressions. I admit to not having much to go on, other than my own memory of history. I'm simply spewing intuition here.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I just took a whiff of a new programming language. Something smelled wrong. &amp;nbsp;It reminded me of&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Fully blown Corba enterprise standards&lt;/li&gt;&lt;li&gt;C++ for business applications&lt;/li&gt;&lt;li&gt;Java for the Web&lt;/li&gt;&lt;li&gt;W3C XML Schema Language&amp;nbsp;&lt;/li&gt;&lt;li&gt;Web Services Standards (pick just about any)&lt;/li&gt;&lt;/ul&gt;It is not that there isn't some merit to each of these, but each&amp;nbsp;egregiously forces a practice of making many decisions early in the design process; they do so in the name of performance; and they all suck because they embed too much cruft in the deployed systems.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The language I smelled was Google's Dart. It smells an awful lot like Java, from the tooling (Eclipse) to the static typing (uh, "optional" static typing). Then there's the &lt;a href="https://gist.github.com/1277224"&gt;17 thousand + line of code "Hello World"&lt;/a&gt; example. But OK, even gcc compiles Hello World to around 8k on an OSX machine. (Then again, that's machine code gcc is compiling into on a desktop, not scripted source in a Web browser.)&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If Google wants to push an alternative to Java, more power to them. But they should not have done it under the pretense of killing JavaScript, or of making open Web scripting easier with enterprise tooling. That's just a little bit "evil".&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6549965850481607898?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6549965850481607898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6549965850481607898' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6549965850481607898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6549965850481607898'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/javascript-is-dead-long-live-javascript.html' title='JavaScript is Dead. Long Live JavaScript'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4894895470928645906</id><published>2012-01-12T10:25:00.000-08:00</published><updated>2012-01-12T10:25:35.489-08:00</updated><title type='text'>SVN Cribs</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-KAt8kA6iGLk/Tw8laGBqATI/AAAAAAAAALQ/wSWW8KeLzSA/s1600/papapishu_cheetah.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-KAt8kA6iGLk/Tw8laGBqATI/AAAAAAAAALQ/wSWW8KeLzSA/s400/papapishu_cheetah.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;(Cheetah credit: Wikipedia Commons)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;svn co https://some.where.no/path/trunk main --username username&amp;nbsp;&lt;yourusername&gt;# "username" is from the server&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svnadmin create reponame   # a local repo (the repo itself, do not modify!)&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;mkdir protouch proj/somefile.txt&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn import proj file:///Users/yourname/reponame/proj -m "Initial import"&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn checkout file:///Users/yourname/reponame/proj proj-copy&lt;br /&gt;svn export file:///Users/yourname/reponame/proj proj-copy   # export instead of checkout&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;cd proj-copy &lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn status&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn update   # Pull changes from server to local; update working copy&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn resolve --accept working    # claim that conflicts were resolved&amp;nbsp;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;&lt;br /&gt;# change, create files&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn add changedfile.txt&lt;br /&gt;svn move oldfilename new filename&lt;br /&gt;svn copy oldfilename new filename&lt;br /&gt;svn delete filename&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn commit -m "made this change"   # commit and push changes to server&lt;br /&gt;svn ci -m "changes comment" filename   # commit for one file&lt;br /&gt;&lt;br /&gt;svn log&lt;br /&gt;svn log filename   # look at log for file&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn diff -r priorversionnumber &lt;br /&gt;svn diff -r ver  filename    # diff only for this file&lt;br /&gt;&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;yourusername&gt;svn update -r priorversionnumber    # roll back to a prior repo state &lt;br /&gt;svn revert FILE&lt;br /&gt;&lt;/yourusername&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;Global options:&lt;br /&gt;  --username ARG           : specify a username ARG&lt;br /&gt;  --password ARG           : specify a password ARG&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;more at &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4894895470928645906?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4894895470928645906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4894895470928645906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4894895470928645906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4894895470928645906'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/svn-cribs.html' title='SVN Cribs'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-KAt8kA6iGLk/Tw8laGBqATI/AAAAAAAAALQ/wSWW8KeLzSA/s72-c/papapishu_cheetah.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5767182561084589775</id><published>2012-01-12T08:35:00.000-08:00</published><updated>2012-01-16T09:37:52.630-08:00</updated><title type='text'>SVN is dead. Long Live SVN</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div style="text-align: left;"&gt;I prefer GIT, but SVN is widespread too. Even though SVN is not very old (it is only 12 years old) but it represents a clone of, rather than a re-imagining of, the antiquated CVS tool (released around 1989). CVS was itself a reworking of the (at the time) popular RCS tool first seen around 1982. RCS inherited its good looks from SCCS, created in 1972 for an IBM System/370. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-kYDTf3Jhrss/Tw8LPtK_JbI/AAAAAAAAAK4/2AaXwBBhn70/s1600/oksmith_dodo_bird.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-kYDTf3Jhrss/Tw8LPtK_JbI/AAAAAAAAAK4/2AaXwBBhn70/s200/oksmith_dodo_bird.png" width="192" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #2e3436; font-family: Arial, Tahoma, sans-serif; font-size: 12px; line-height: 13px;"&gt;(Dodo credit Wikimedia Commons)&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;So the core concepts that frame up SVN are over forty years old. The workflows have changed with each re-implementation, but the basic approach to version control is pretty similar. Vaguely, the way these tools work can be characterized by a few features:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;there is a single central point of update&amp;nbsp;&lt;/li&gt;&lt;li&gt;changes are tracked one file at a time&lt;/li&gt;&lt;ul&gt;&lt;li&gt;it is left to the user to use labeling and other tool features to ensure that sets and subsets of files corresponding to systems and modules are self-consistent and sane configurations&amp;nbsp;&lt;/li&gt;&lt;li&gt;histories must be computed in a more or less unbroken chain&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;filesystem level changes, and special file types, are not tracked well, or not at all&lt;/li&gt;&lt;ul&gt;&lt;li&gt;renames are not well tracked&lt;/li&gt;&lt;li&gt;file history can easily be lost&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;higher level constructs for configuration versioning are missing&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;no symbolic tagging&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;branching is clumsy, heavyweight, long-lived, and error-prone&lt;/li&gt;&lt;li&gt;data and metadata access is rigid and fragile, but fast&lt;/li&gt;&lt;ul&gt;&lt;li&gt;repositories are exposed to corruption from trivial user level actions&lt;/li&gt;&lt;li&gt;SVN is both faster and more robust, but still trivially easy to corrupt by network errors and faulty clients&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;OK, maybe this is being a bit unfair, incomplete, abstract, and irrelevant as judged by an SVN expert. &amp;nbsp;I admit to having&amp;nbsp;&lt;i&gt;completely&lt;/i&gt;&amp;nbsp;lost interest in the SCCS evolutionary branch of VCS's when&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/GNU_Arch"&gt;Tom Lord's Arch (tla)&lt;/a&gt;&amp;nbsp;arrived on the scene in 2001.&lt;br /&gt;&lt;ol style="text-align: left;"&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div style="text-align: left;"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-u_e_2xvQOvc/Tw8Vc9_10gI/AAAAAAAAALI/9IhnQzhkjMI/s1600/finchvarietal.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-u_e_2xvQOvc/Tw8Vc9_10gI/AAAAAAAAALI/9IhnQzhkjMI/s320/finchvarietal.png" width="303" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;(Original finch image credit Wikipedia Commons)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;The vine that was TLA died but not before sparking a vibrant ecosystem of competing Distributed Revision Control systems. &amp;nbsp;My recollection could have gaps, but to my mind Tom Lord never really got the credit he deserved for this innovation.&amp;nbsp;Mercurial and GIT are two modern representatives of this evolutionary genus.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-nnqyCYl1Ygg/Tw8NWsPYsDI/AAAAAAAAALA/JpFf8_DRUQM/s1600/papapishu_cheetah.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="192" src="http://2.bp.blogspot.com/-nnqyCYl1Ygg/Tw8NWsPYsDI/AAAAAAAAALA/JpFf8_DRUQM/s320/papapishu_cheetah.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #2e3436; font-family: Arial, Tahoma, sans-serif; font-size: 12px; line-height: 13px;"&gt;(Cheetah credit Wikimedia Commons)&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;While the SCCS-&amp;gt;RCS-&amp;gt;CVS-&amp;gt;SVN branch has thrived in the open source community, it remains a rather stilted lineage. This isn't because SVN is a mature tool now (although it is). &amp;nbsp;Rather, it is because SCCS had fixed in place a large number of decision points that were not (or could not be) revisited even when its descendants broadened and matured the design. Up to a gross approximation of workflow, SCCS == RCS == CVS == SVN. Further diversification has a very high cost and low payback, and so no richness of form will arise from that fount.&lt;br /&gt;&lt;br /&gt;For a more positive spin, read about the &lt;a href="http://thinkvitamin.com/code/why-you-should-switch-from-subversion-to-git/"&gt;advantages of a distributed VCS on ThinkVitamin&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5767182561084589775?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5767182561084589775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5767182561084589775' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5767182561084589775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5767182561084589775'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/svn-is-dead-long-live-svn.html' title='SVN is dead. Long Live SVN'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-kYDTf3Jhrss/Tw8LPtK_JbI/AAAAAAAAAK4/2AaXwBBhn70/s72-c/oksmith_dodo_bird.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7858608491200048823</id><published>2012-01-06T12:39:00.000-08:00</published><updated>2012-01-06T13:01:09.461-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='Node.js'/><title type='text'>Check out the Node Beginner Book</title><content type='html'>Check out &lt;a href="http://nodebeginner.org/"&gt;http://nodebeginner.org/ &lt;/a&gt;&amp;nbsp;, the Node Beginner Book.&lt;br /&gt;&lt;br /&gt;This is an unprovoked, unpaid, unrequited plug, just because I enjoyed looking through the site and working out the example. There is ample room to tweak the idiomatic style and play with the example, which is completely straightforward. The writing is a tiny amount sugary, but it presents a very good narrative. This guy needs to write more user guides. &amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7858608491200048823?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7858608491200048823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7858608491200048823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7858608491200048823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7858608491200048823'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/check-out-node-beginner-book.html' title='Check out the Node Beginner Book'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7039013830252872998</id><published>2012-01-01T08:35:00.001-08:00</published><updated>2012-01-02T06:44:34.442-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Node.js'/><title type='text'>Reading Blocks in POW and Node.js</title><content type='html'>A writer's block is when you've got some serious motivation to write, but can't seem to find the inspiration to get started or the cleverness to get past a simple difficulty. &amp;nbsp;Readers can face blocks too, especially when the writer has done a poor job of weaving the threads of the story and bringing them together.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The same problems exist for programmers when writing and reading code, except much more so. &amp;nbsp;As programmers, we often need to tease out the answers to questions about where some control path came from, and were it is going.&lt;br /&gt;&lt;br /&gt;I'm thinking now of a snag hit while trying to convert my personal site to use HTML5's caching manifests:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;code&gt;Application Cache Error event: Invalid manifest mime type (application/octet-stream) http://mitch.amiano.agilemarkup.com.dev/manifest.cache&lt;/code&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was using the &lt;a href="https://github.com/37signals/pow"&gt;37Signals' POW server&lt;/a&gt; to do my local testing. &amp;nbsp;It looks like POW serves up the manifest file as an octet stream, instead of the recommended type (text/cache-manifest)&lt;span style="background-color: white; font-family: sans-serif;"&gt;.&lt;/span&gt;&amp;nbsp;I searched for the mime type handling in POW. It is not there. As a reader, I face a small block.&lt;br /&gt;&lt;br /&gt;POW is reusing modules defined in&amp;nbsp;&lt;a href="https://github.com/joyent/node"&gt;Node.js&lt;/a&gt;, the V8 evented I/O library. So naturally, there is nothing present in the POW source code base that will clarify how it resolves missing mime types.&lt;br /&gt;&lt;br /&gt;More precisely, POW is calling a connect.static method. There is no "connect" module in POW or Node.js, and nothing in the source code base that would suggest what "connect" is, other than an anonymous Node.js module. So we have to search elsewhere, elusively.&lt;br /&gt;&lt;br /&gt;Implicit in using Node.js is use of a flat global namespace for modules, implemented by npm, the &lt;a href="https://github.com/isaacs/npm"&gt;Node Package Manager&lt;/a&gt;. It isn't clear to me how (or whether) npm manages versions, or what people will do if and when a competing package manager is released, or when packages adopt similar or identical names. It seems as if git repo urls are implicit in the packaging, but not in any way that is definitive in the client source code.&lt;br /&gt;&lt;br /&gt;Now, a programmer who is experienced in a given library will become a priest, familiar with all the dangling threads of the righteous library. But that's no excuse for leaving threads dangling. This is the stuff of a cult-like priesthood, not of a profession. &amp;nbsp;all a bit of a guessing game.&lt;br /&gt;&lt;br /&gt;[edit: turns out that Node uses package.json for version/dependency management; however, unless you've downloaded all the sources, UNIX tools like "find" or "grep" will obviously not find anything.]&lt;br /&gt;&lt;br /&gt;Connect is &lt;strike&gt;(very probably)&amp;nbsp;&lt;/strike&gt;&lt;strike&gt;some&lt;/strike&gt;&amp;nbsp;a version &lt;strike&gt;(which one???)&lt;/strike&gt; of a Node.js based &lt;a href="https://github.com/senchalabs/connect"&gt;middleware framework&lt;/a&gt;. &amp;nbsp;specified by package.json in the root of the source tree. The git repo says that static is a middleware module packaged with connect. The static middleware calls mime.lookup(path). &amp;nbsp;The mime package and version are not anywhere to be seen in the Connect source code. I'm seeing a pattern here, or rather an anti-pattern.&lt;br /&gt;&lt;br /&gt;References should not be more exact than necessary, but nor should they be so ambiguous that they contain insufficient information to find the referenced entity.&lt;br /&gt;&lt;br /&gt;So I locally clone Connect, and Node.js, and POW, and use OSX' find command to sniff out the possible locations of the mime type handling, to see if there is an idiomatic way of adding a new type.&amp;nbsp;The mime module is a package included with Node.js, down in&amp;nbsp;deps/npm/node_modules/request/mimetypes.js.&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;I'm repeating myself, but the mime module&amp;nbsp;is not part of the Connect source code base, and I have to assume that it isn't referring to some other module also called "connect".&amp;nbsp;&amp;nbsp;This case is simple enough - mimetypes.js is just an associative array with a lookup function - but in the general case, which version might we be linking to, and who is the owner?&lt;/strike&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;strike&gt;Writing like this isn't just an interruption to the reader, it is a failure of the writer to pull together the threads of the story. That makes the story more difficult to follow than necessary, and it isn't sufficient to deliver a reliable piece of software except by fortunate accident. &lt;/strike&gt;&lt;br /&gt;&lt;br /&gt;Avoiding searches for ambiguous references is what Integrated Development Environments were designed for. &amp;nbsp;But using an IDE is missing the point: it shouldn't be necessary when reading sources to go through an unreliable search for every dependency. &lt;br /&gt;&lt;br /&gt;&lt;br class="Apple-interchange-newline" /&gt;I'll chalk this up to my own inexperience with Node.js.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;strike&gt;Maybe&lt;/strike&gt; I &lt;strike&gt;don't&lt;/strike&gt;&amp;nbsp;didn't grok Node.js and npm well enough&lt;strike&gt; yet&lt;/strike&gt;. &lt;strike&gt;Maybe there are some conventions that make the resolution more definitive and repeatable.&lt;/strike&gt;&amp;nbsp;The convention requires that you use npm like one would use bundler and gems in Ruby.&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;But writing code that requires mental long-jumps to anonymously named, un-versioned modules seems like a very stupid way to program. &amp;nbsp;Perhaps&amp;nbsp;Node.js needs its own version of bundler.&lt;/strike&gt;&lt;br /&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;br /&gt;[edit: Yeah, node.js &lt;i&gt;has&lt;/i&gt;&amp;nbsp;its own means of packaging components -- I had missed that in my haste. I still think there is a disconnect between where entities are defined and where they are used by clients... the dependencies wind a path through multiple packages, give opportunity for mysteriously similar names amongst package methods and variables, and generally make piecing together the story more difficult than it needs to be.]&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7039013830252872998?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7039013830252872998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7039013830252872998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7039013830252872998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7039013830252872998'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2012/01/blog-post.html' title='Reading Blocks in POW and Node.js'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2501221769164474794</id><published>2011-12-29T16:00:00.000-08:00</published><updated>2011-12-29T16:00:16.350-08:00</updated><title type='text'>Selling Yourself Out of Projects</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So, a friend tells me about a buddy who "has a software project you can help him with."&lt;br /&gt;&lt;br /&gt;Prospects are very subjective creatures. I tend to think that a professional, whether a software craftsperson or an engineer, or something else, has a kind of fiduciary ethic even toward prospects. If a prospect asks about developing a software project, my immediate concerns are&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;Does the client really need custom development?&lt;/li&gt;&lt;li&gt;Is there an existing service that already meets their needs?&lt;/li&gt;&lt;li&gt;Will the recurrent tangible and intangible costs &amp;nbsp;(of any desired path) present an impractical future burden ?&lt;/li&gt;&lt;/ol&gt;Unqualified prospects would result in No to the first question and/or Yes to the second question. &amp;nbsp;The third question is one that no salesperson in their right mind would venture to probe, but it represents a core value of the engineering ethos. &amp;nbsp;Is the prospect willing &lt;i&gt;and able&lt;/i&gt; to accept the costs?&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;I'm in my right mind, but I'm not as much a salesperson as my friend. &amp;nbsp;So I informed the prospect of his options and alternatives early, and gave him some context of the cost. That approach pre-qualifies many prospects out of project, or at least, sends them looking for someone else who is more willing to lead clients down a primrose path.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The thing is, my friend would have just jumped into the job, sweeping questions about the likely costs under the rug, &amp;nbsp;playing dumb about the prospect's needs and getting them to pay for scraps of functionality as soon as possible. &amp;nbsp;This sort of drive-by software development is all too common.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;I'd rather sell myself out of a project than put blinders on and lead prospects down a rabbit hole. That may not be the magical thinking that fuels so many Law of Attraction acolytes, but it is the path an ethical person will tend to follow.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2501221769164474794?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2501221769164474794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2501221769164474794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2501221769164474794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2501221769164474794'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/selling-yourself-out-of-projects.html' title='Selling Yourself Out of Projects'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5066166781599492473</id><published>2011-12-22T13:13:00.000-08:00</published><updated>2011-12-22T13:13:14.750-08:00</updated><title type='text'>Unconscientious Prospects</title><content type='html'>&lt;br /&gt;&lt;div class="p1"&gt;I was contacted recently via email, by a prospect seeking assistance with a small PHP/MySQL project. Now, disregarding my personal distaste for Rube Goldberg skunkworks cobbled together in PHP, I offered to help anyway.&amp;nbsp;Paraphrasing the conversation&amp;nbsp;it went something like this:&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;b&gt;Prospect:&lt;/b&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;Hi, I was given your name by *********. &amp;nbsp;I have a web based tool and would like to make minor modifications to it. I want to remove some functions for a one-time use.&amp;nbsp; It should not be very involved or big task but I need to have it up and running &amp;nbsp;in three weeks.&amp;nbsp; If you think you might be interested please let me know.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;b&gt;Me:&lt;/b&gt; (replying a few hours later)&lt;/div&gt;&lt;div class="p1"&gt;&lt;/div&gt;&lt;div class="p2"&gt;I'd be happy to discuss your needs for the Web tool. &amp;nbsp;If you would like to talk, I have some time this week. Let me know.&amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;b&gt;Prospect:&lt;/b&gt; (no reply for two days)&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;b&gt;Me: &lt;/b&gt;(two days later, this time with a return receipt attached)&lt;/div&gt;&lt;div class="p2"&gt;Hi, I just wanted to follow up to make sure you received my reply. Are you still looking for assistance?&amp;nbsp;&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;b&gt;Prospect:&lt;/b&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;/div&gt;&lt;div class="p1"&gt;Hi, got follow up from someone else before your reply.&amp;nbsp; Will need to do some other work and will get in touch with you when I am ready.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;b&gt;Me:&lt;/b&gt;&lt;/div&gt;&lt;div class="p1"&gt;My immediate knee-jerk reaction to this was, "hey, someone beat me to it, good for them!" but then a couple of thoughts occurred:&lt;/div&gt;&lt;div class="p1"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;It is unprofessional to ask someone for help, then ignore their attempts to communicate. &lt;br /&gt;&lt;br /&gt;Everyone gets distracted once in a while, but even if you aren't immediately going to do business with someone, if they extended the courtesy of a reply you owe them the same courtesy in return.&lt;br /&gt;&lt;br /&gt;The oblivious lack of courtesy of dropping an email exchange is like walking through a door and letting it slam shut in the face of the person behind you. It isn't very pleasant to the slam-e, and it reflects poorly upon you.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Conversely, if you judge suitability based upon the how quickly one responds, you aren't looking for a relationship but a one-night stand.&lt;br /&gt;&lt;br /&gt;Look, as a freelance programmer I'm not seeking to date you or marry you. &amp;nbsp;But I do have an expectation of a certain amount of reciprocal attentiveness and return on my investment of time. &amp;nbsp;Treating your search for help as if you are casting chum and netting the first fish that bites, shows that you are not very&amp;nbsp;conscientious. Or at least, when push comes to shove you become neglectful. &amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;I'm less and less interested in giving people second chances, perhaps because I've often been so long-suffering on the first go-round. &amp;nbsp;What is really beginning to annoy me though is the attitude that we're just "resources" or "commodities". &amp;nbsp;Damn it, Jim, I'm a person, not a commodity. &amp;nbsp;If you care so little about who you employ &lt;i&gt;and&lt;/i&gt; you can't communicate&amp;nbsp;&lt;i&gt;and&lt;/i&gt; you consider the effort to be so small, why would I want to bother doing business with you?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5066166781599492473?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5066166781599492473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5066166781599492473' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5066166781599492473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5066166781599492473'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/unconscientious-prospects.html' title='Unconscientious Prospects'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2142253171276832455</id><published>2011-12-16T11:52:00.000-08:00</published><updated>2011-12-16T14:33:24.401-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Standards'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Grammar Considered Wrong</title><content type='html'>I get a little &lt;span class="pumpline"&gt;nit-picky&lt;/span&gt; every time I look at CSS.&lt;br /&gt;Take the way that the &lt;a href="http://www.w3.org/TR/css3-mediaqueries/#width"&gt;media queries spec&lt;/a&gt; handles dimensions like width and height. They couldn't just say "width", no, no, that would be just too easy. Instead they say min-width, width, and max-width.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/nationalmediamuseum/3588575305/" title="Flea microphotograph by National Media Museum, on Flickr"&gt;&lt;img alt="Flea microphotograph" height="200" src="http://farm4.staticflickr.com/3332/3588575305_3d3b73e8e6.jpg" width="175" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;CSS grammar is meant to be declarative, but that's not the reason for using prefixes.&amp;nbsp;The &lt;a href="http://www.w3.org/TR/css3-mediaqueries/#media1"&gt;CSS media queries section&lt;/a&gt; on media features tries to explain the rationale:&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Most media features accept optional ‘min-’ or ‘max-’ prefixes to express "greater or equal to" and "smaller or equal to" constraints. This syntax is used to avoid "&amp;lt;" and "&amp;gt;" characters which may conflict with HTML and XML. Those media features that accept prefixes will most often be used with prefixes, but can also be used alone.&lt;/blockquote&gt;&lt;br /&gt;Never mind that CSS selectors &lt;a href="http://www.w3.org/TR/CSS2/selector.html#child-selectors"&gt;already use the greater-than symbol&lt;/a&gt;.&amp;nbsp;The grammar has gotten land-locked, but it has never used commonly accepted notation for mathematical expressions. You know, expressions such as:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;width: (160,320) &amp;nbsp; (interval notation)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;160 &amp;lt; width &amp;lt; 320 &amp;nbsp; (set builder notation)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;(160..320,true).include? width &amp;nbsp; (Ruby, using a range)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;width BETWEEN 160 AND 320 &amp;nbsp; (SQL)&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Whatever. The nit I'm picking is not that the CSS editors have had to work with what they've inherited.&lt;br /&gt;&lt;br /&gt;Whether an historical accident or pragmatic contingency, using prefixes&amp;nbsp;(min-, max-) on property names as grammatical substitutes for logic expressions (&amp;gt;=, &amp;lt;= respectively) constitutes a multiplication of entities way beyond necessity.&amp;nbsp;Instead of one property (width) within two scopes (logical and device), CSS presents us with:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;device-width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;min-width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;min-device-width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;max-width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;max-device-width&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;aspect-ratio &amp;nbsp; (CSS pixel width/height)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;device-aspect-ratio&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;min-aspect-ratio&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;max-aspect-ratio&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;min-device-aspect-ratio&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;max-device-aspect-ratio&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;orientation &amp;nbsp;(width &amp;gt; height ? landscape : portrait )&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Them's &lt;span class="pumpline"&gt;A DOZEN MORE&lt;/span&gt;&amp;nbsp;properties, baby.&lt;br /&gt;That's just for one stinkin' property,&amp;nbsp;so don't be callin' me all pedantic on this. &amp;nbsp;&amp;nbsp;If y'all leave nits alone they grow and&amp;nbsp;soon&amp;nbsp;enough you find yourself infested with lice. (Not that I have any experience with lice.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;aside&gt;Yes, I've included properties like orientation and aspect ratio in there. Why? Because they are computable, or more precisely, functionally dependent upon width and height. Therein lies a difficulty with CSS: it has no computable functions.&amp;nbsp;The lack of computation is a design constraint of the language, and for the most part it seems to have been the right choice. The consequence is redundant expressions and overlapping semantics, where the only way to cover expressive gaps is to go outside of CSS to a language on the server-side (SASSy CSS) or client-side (JavaScript). &lt;br /&gt;&lt;/aside&gt;&lt;br /&gt;The gratuitous prefixes don't make the resulting media queries any more elegant to express:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;@media screen and (min-width: 160) and (max-width: 320) { &lt;br /&gt;&amp;nbsp; stuff {&amp;nbsp;&amp;nbsp;goes: here; &amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The problem is that CSS uses a fixed set of discretely expressed predicates for continuous and dynamically varying values. What I want it to say instead is something more along the lines of:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;@media screen and (160 &amp;lt; width &amp;lt; 320) )&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&amp;nbsp; stuff {&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: monospace;"&gt;&amp;nbsp;goes: here; &amp;nbsp;&lt;/span&gt;&lt;span style="font-family: monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: monospace;" /&gt;}&lt;/code&gt;&lt;br /&gt;or&lt;br /&gt;&lt;code&gt;@media screen and (width: range(160..320) ) )&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&amp;nbsp; stuff {&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: monospace;"&gt;&amp;nbsp;goes: here; &amp;nbsp;&lt;/span&gt;&lt;span style="font-family: monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: monospace;" /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;CSS is what it is and for better or worse this design choice passed through the editing and public commentary process intact. &amp;nbsp;Other efforts can still learn from its missteps as much as its successes. &amp;nbsp;Injecting special-case grammatical devices is an easy way to make a language available early but injecting them often will&amp;nbsp;&lt;a href="http://www.bonkersworld.net/images/2011.11.15_life_of_a_swe.png"&gt;turn even a greenfield language into yet another Rube Goldberg device&lt;/a&gt;. As a device, CSS has more than a little Rube Goldberg in it.&amp;nbsp;&lt;/div&gt;&lt;style&gt;.pumpline {  font-size: 3.22em;  font-weight: bold;  vertical-align: -16%;}&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2142253171276832455?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2142253171276832455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2142253171276832455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2142253171276832455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2142253171276832455'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/css-grammar-considered-wrong.html' title='CSS Grammar Considered Wrong'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7608600486611544949</id><published>2011-12-13T20:02:00.001-08:00</published><updated>2011-12-13T20:14:16.996-08:00</updated><title type='text'>Dropped Google Ads</title><content type='html'>For a long time, I had a little sidebar of Google ads displayed on my blog. No more.&lt;br /&gt;&lt;br /&gt;At the time it seemed like the thing to do. Syndicated advertising was all the rage, everyone was supposed to find ways to monetize their sites, blah blah blah...&lt;br /&gt;&lt;br /&gt;I just threw up the sidebar to go through the steps needed, in case I needed to do it for someone else and just out of curiosity to see what it would generate.Well, this blog is, should we say, along the road less travelled, so the ads never amounted to anything monetarily.&lt;br /&gt;&lt;br /&gt;It turns out that Google ads looked really sucky when the mobile template was active. Actually, they look sucky any time, but their relative sucky-ness increases as the display window decreases. I don't know why, they were just ugly.&lt;br /&gt;&lt;br /&gt;There was another downside too: besides detracting from the visuals, syndicated advertisements contradict one of the messages of the blog: our society has put so much of its human capital into manipulating perceptions that it has eaten away at workplace ethics and cannibalized its equity in the process.&lt;br /&gt;&lt;br /&gt;Bye bye, Google ads, I'm not really going to miss you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7608600486611544949?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7608600486611544949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7608600486611544949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7608600486611544949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7608600486611544949'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/dropped-google-ads.html' title='Dropped Google Ads'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7261642693272842956</id><published>2011-12-12T05:07:00.001-08:00</published><updated>2011-12-12T07:03:32.450-08:00</updated><title type='text'>Musings on consciousness</title><content type='html'>Janice Janes had a very informal, very anecdotal hypothesis: before the human condition first acquired consciousnes, our existence was dictated by a non self-aware construct he termed the bicameral mind. Janes argues that the development of consciousness is in part language based, and in part wired into our brains, based upon the authority structures of the culture. Consciousness thus developed over time as the challenges of dealing with multiple interacting cultures forced the simple structures to break down and be reconstituted, generation after generation. &lt;br /&gt;&lt;br /&gt;I don't know whether Janes' ideas were away in left field or in any way mainstream, but they were intriguing. Through his lens it was easy to interpret xenophobia, black and white doctrines, separatism, etc. as attempts by a subculture to regain some measure of the simplicity of the less self-reflective mind. &lt;br /&gt;&lt;br /&gt;Janes' assumptions that consciousness was/is an ever progressing evolutionary eventuality are wrong. Cultures can and do move backwards towards a less than fully conscious hive mind mentality. If anything, consciousness is Lamarkian, not Darwinian. Consider the culture of Afghanistan, or, closer to home, religious cults. Fanatical followers of media personalities such as Oprah or Jim Bakker (not to say they are equivalent however) oven have great difficulty separating their own opinons from those espoused by their glorified leaders. Prejudice is the antithesis of consciousness.&lt;br /&gt;&lt;br /&gt;And it isn't just about collectivist authority structures, but personal identity. Experience of the world drives consciousness about that world. Less experience implies a narrow, specialized focus but also a limit to consciousness. Ignorance is bliss. Experiences by proxy, as through the Web and TV, create a consciousness that does not accurately image or respond to the physical and social world. In this case, ignorance is not bliss as the conflicting and falsified viewpoints creates unnecessary and unhelpful reflection.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7261642693272842956?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7261642693272842956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7261642693272842956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7261642693272842956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7261642693272842956'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/musings-on-consciousness.html' title='Musings on consciousness'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4924981485060101411</id><published>2011-12-08T20:16:00.001-08:00</published><updated>2011-12-09T10:40:36.990-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Autocatalysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming by Side-Effect'/><category scheme='http://www.blogger.com/atom/ns#' term='Crowd Sourcing'/><title type='text'>Autocorrective Crowd Sourcing and Autocatalytic Systems Programming</title><content type='html'>So, a friend sends me this link about how Recapcha is being used to pawn off digitizing work to unsuspecting users, in an ingenious manner:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="374" width="526"&gt;&lt;param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="bgColor" value="#ffffff"&gt;&lt;/param&gt;&lt;param name="flashvars" value="vu=http://video.ted.com/talk/stream/2011X/Blank/LuisVonAhn_2011X-320k.mp4&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/LuisVonAhn_2011X-embed.jpg&amp;vw=512&amp;vh=288&amp;ap=0&amp;ti=1295&amp;lang=&amp;introDuration=15330&amp;adDuration=4000&amp;postAdDuration=830&amp;adKeys=talk=luis_von_ahn_massive_scale_online_collaboration;year=2011;theme=the_rise_of_collaboration;event=TEDxCMU;tag=Technology;tag=collaboration;tag=computers;tag=internet;tag=language;&amp;preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /&gt;&lt;embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="526" height="374" allowFullScreen="true" allowScriptAccess="always" flashvars="vu=http://video.ted.com/talk/stream/2011X/Blank/LuisVonAhn_2011X-320k.mp4&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/LuisVonAhn_2011X-embed.jpg&amp;vw=512&amp;vh=288&amp;ap=0&amp;ti=1295&amp;lang=&amp;introDuration=15330&amp;adDuration=4000&amp;postAdDuration=830&amp;adKeys=talk=luis_von_ahn_massive_scale_online_collaboration;year=2011;theme=the_rise_of_collaboration;event=TEDxCMU;tag=Technology;tag=collaboration;tag=computers;tag=internet;tag=language;&amp;preAdTag=tconf.ted/embed;tile=1;sz=512x288;"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Setting aside for the moment any ethical considerations of virtual slavery and digitally indentured servitude, it really is a masterful plan.&lt;br /&gt;&lt;br /&gt;The crowd sourcing model can even be used to clean up application data, even when the crowd is relatively small.&lt;br /&gt;&lt;br /&gt;Another friend related the case where a US federal government department contacted him, to consult on &amp;nbsp;scrubbing business names from a terabyte scale database. The chief difficulty is that much of the data originated by people typing in whatever they wanted. My friend rightly points out that it is always cleaner to select a coded value from a list, rather than allow free form typing. That is not possible when the values vary, as human contrivances (company names) frequently do.&lt;br /&gt;&lt;br /&gt;Systems may be designed to allow people to type in new names in a free form manner.&amp;nbsp;Free form data input means Garbage in, Garbage out: there is no way to identify the unbounded variation of lexical strings by which a company name is known. Consider the morphisms of the Johnson &amp;amp; Johnson corporate apellation:&lt;br /&gt;&lt;br /&gt;Johnson and Johnson&lt;br /&gt;Johnson &amp;amp; Johnson&lt;br /&gt;Johnson &amp;amp; Johnson, Inc.&lt;br /&gt;Johnson and Johnson, Incorporated&lt;br /&gt;J&amp;amp;J,&lt;br /&gt;J &amp;amp; J,&lt;br /&gt;J&amp;amp; J,&lt;br /&gt;J. &amp;amp; J. ,&lt;br /&gt;J and J&lt;br /&gt;jnj.com&lt;br /&gt;&lt;br /&gt;The letter case is not such a big deal. Neither is the variation of whitespace, or even the substitution of the ampersand for the word "and". &amp;nbsp;The problem is that the set of these names is finite but unbounded and the set changes over time. There is no easy way of identifying entries that go with the&amp;nbsp;canonical&amp;nbsp;name for a given organization.&lt;br /&gt;&lt;br /&gt;Or isn't there? Applications capture this data in daily interactions with users. Combo boxes can list previous entries and make coded selections, while allowing novel inputs. &amp;nbsp;So use string pattern matching to do a lookup of the possibilities based upon the first few characters typed. But don't look into the old records, look into a map of generated and collected synonyms instead. &lt;br /&gt;&lt;br /&gt;Allow the user to start entering the name of the company. If after the first few letters, you find an exact match on a canonical name and the user accepts it, you're done: just take the code for the canonical name. If there are no perfect matches, generate a set of weighted regexp patterns based upon the user input; any original names that match and are accepted by the user are recorded as a probable match for future lookups.&lt;br /&gt;&lt;br /&gt;That is admittedly rather sketchy, but I'm sure someone has implemented a few schemes along these lines to clean up old data. What would some of the advantages be?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cost is not incurred when the effort has no value.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Data for companies that are no longer participating is not touched.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Effort is expended whenever it is needed.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Data for companies that are participating often are improved more rapidly.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Refinement of the data set is embedded as a design feature of the system.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Not one-shot: Cleaning of the data continues over the lifespan of the system.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Tracks the moving target: Data set targets are ambiguous symbols representing shifting human contrivances (businesses). &amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;Can the strategy work? &amp;nbsp;Biological systems do something analogous in the form of DNA error detection and repair. They are far from perfect, but organisms maintain their integrity for decades, up to hundreds of years... thousands if you consider some of the oldest organisms like trees and fungi.&lt;br /&gt;&lt;br /&gt;The key idea here is accepting that determinism in complex systems is a convenient myth that is sometimes more trouble than it is worth. &amp;nbsp;That realization opens the way for explicitly probabilistic feedback loops -- just one more way for complex computer systems to fulfill their original design intent to illuminate the processes of life.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4924981485060101411?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4924981485060101411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4924981485060101411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4924981485060101411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4924981485060101411'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/autocorrective-crowd-sourcing-and.html' title='Autocorrective Crowd Sourcing and Autocatalytic Systems Programming'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2475125575357425831</id><published>2011-12-06T16:13:00.001-08:00</published><updated>2011-12-08T19:20:32.769-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>Attending Triangle JS Meetup</title><content type='html'>I'm attending the Triangle JavaScript Meetup tonight. They're discussing &lt;a href="http://mulberry.toura.com/"&gt;Toura Mulberry&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8Um4Lrm6k_s/Tt-3XlvoFxI/AAAAAAAAAEM/b27b6CU00qw/s1600/flickr-3539594171-original.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="272" src="http://3.bp.blogspot.com/-8Um4Lrm6k_s/Tt-3XlvoFxI/AAAAAAAAAEM/b27b6CU00qw/s320/flickr-3539594171-original.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="background-color: #2b2b2b; color: #8b8b8b; font-family: 'Lucida Grande', 'Trebuchet MS', Arial, sans-serif; font-size: 11px; font-weight: bold; line-height: 20px; white-space: nowrap;"&gt;the original photo is by&amp;nbsp;&lt;/span&gt;&lt;a about="http://images.cdn.fotopedia.com/flickr-3539594171-original.jpg" class="external_author" href="http://www.fotopedia.com/redirect?u=http%3A%2F%2Fwww.flickr.com%2Fphotos%2F41597043%40N00" property="cc:attributionName" rel="cc:attributionURL" style="background-color: #2b2b2b; color: #cbcbcb; font-family: 'Lucida Grande', 'Trebuchet MS', Arial, sans-serif; font-size: 11px; font-weight: bold; line-height: 20px; text-decoration: none; white-space: nowrap;" target="_blank"&gt;mauroguanandi&lt;/a&gt;&lt;span class="Apple-style-span" style="background-color: #2b2b2b; color: #8b8b8b; font-family: 'Lucida Grande', 'Trebuchet MS', Arial, sans-serif; font-size: 11px; font-weight: bold; line-height: 20px; white-space: nowrap;"&gt;&amp;nbsp;on&amp;nbsp;&lt;/span&gt;&lt;a about="http://images.cdn.fotopedia.com/flickr-3539594171-original.jpg" class="external_photo" href="http://www.fotopedia.com/redirect?u=http%3A%2F%2Fwww.flickr.com%2Fphotos%2F41597043%40N00%2F3539594171" property="cc:attributionName" rel="cc:attributionURL" style="background-color: #2b2b2b; color: #cbcbcb; font-family: 'Lucida Grande', 'Trebuchet MS', Arial, sans-serif; font-size: 11px; font-weight: bold; line-height: 20px; text-decoration: none; white-space: nowrap;" target="_blank"&gt;Flickr&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The open source mobile development and deployment tool, not the fruit. @rmurphey from Toura is presenting.&lt;br /&gt;&lt;br /&gt;Mulberry is a toolchain and deployment strategy wrapped around PhoneGap. The unofficial description is that it follows a Rails-like approach to the toolchain. As far as deployment is concerned, Mulberry acts as an HTML browser in a private application.&lt;br /&gt;&lt;br /&gt;Mulberry attempts to be a full-cycle development stack for applications deployed as embedded Web-browser (using Sinatra?), displaying content from JSON. Most of the responsibility for presentation sits on the mobile device, implemented in JavaScript. In fact, most of the HMTML and markdown gets converted into JSON content data, which is then composed into DOM by JavaScript on the client.&lt;br /&gt;&lt;br /&gt;Like Rails, Mulberry is opinionated, and provides generators for scaffolding. It relies upon the exposure of content through a "node" interface to publish data. Several of the artifacts created with the generator are configuration files for things like the media form factors, devices, site map, default content (in markdown), routes, etc. The system is then immediately available to test using "mulberry serve", the built-in server, without a build process. Also like Rails, the system uses special URL formats to convey configuration settings in the running app.&lt;br /&gt;&lt;br /&gt;Basically, Mulberry is a single page, off-line application meant for quick deployment.&lt;br /&gt;&lt;br /&gt;Mulberry sends most of the content down as a static set of nodes, but the deployment wrapper supports polling for content refreshes. Currently that functionality is limited to content, not including templates or behavior, due to Apple Store guidelines.&lt;br /&gt;&lt;br /&gt;Also mentioned&lt;br /&gt;&lt;a href="http://ripple.tinyhippos.com/"&gt;Ripple&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/callback/callback-weinre"&gt;Weinre&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.iwebinspector.com/"&gt;iWebInspector&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2475125575357425831?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2475125575357425831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2475125575357425831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2475125575357425831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2475125575357425831'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/attending-triangle-js-meetup.html' title='Attending Triangle JS Meetup'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-8Um4Lrm6k_s/Tt-3XlvoFxI/AAAAAAAAAEM/b27b6CU00qw/s72-c/flickr-3539594171-original.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6910739241883766195</id><published>2011-12-03T06:36:00.001-08:00</published><updated>2011-12-08T19:21:58.993-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Health'/><category scheme='http://www.blogger.com/atom/ns#' term='Science-Technology-Engineering-Math (STEM)'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><title type='text'>Thinking matters, even in Condé Nast magazines</title><content type='html'>I'm on a quest to get healthier despite my programmer ways, and I do a fair bit of researching. To that end, I review medical literature from databases like &lt;a href="http://www.ncbi.nlm.nih.gov/pubmed/"&gt;PubMed&lt;/a&gt;/Medline, and look for the reasons supporting or conflicting with pop-culture (including government) recommendations. &lt;br /&gt;&lt;br /&gt;In my perusing, I came across a &lt;a href="http://nutritiondata.self.com/foods-000011000000000000000-1.html?"&gt;nutritional site about the Fructose content of various foods&lt;/a&gt;, operated by &lt;a href="http://www.self.com/"&gt;SELF Magazine&lt;/a&gt;. &amp;nbsp;That's good, because fructose acts like alcohol to the liver, leading to cirrosis, insulin resistance and diabetes, which is bad.&lt;br /&gt;&lt;br /&gt;SELF is one of those Condé Nast periodicals aimed squarely at the well-off-but-otherwise-insecure-young-female crowd. &amp;nbsp;I'm trying to limit the intake of high fructose foods in my lifestyle, and if is informative to hot, wealthy, young women surely I can use it too.&lt;br /&gt;&lt;br /&gt;Except it doesn't matter if we&amp;nbsp;guys have almost all the same genes as gals and fructose doesn't seem to respect any of the differences...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://thepwnzone.files.wordpress.com/2011/07/hot-girl-fail-pic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://thepwnzone.files.wordpress.com/2011/07/hot-girl-fail-pic.jpg" width="249" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;...because as presented the site offers utterly bogus information. In fact, the data is often upside-down.&lt;br /&gt;&lt;br /&gt;Let's take a look and make some conclusions based on the site's rankings:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Molasses has half the fructose content of iceberg lettuce&lt;/li&gt;&lt;li&gt;Applesauce is ranked higher (worse) than honey&lt;/li&gt;&lt;li&gt;Plums and onions are almost the same&lt;/li&gt;&lt;li&gt;Celery is at #179, within the top 200, having 6.4 grams of Fructose&lt;/li&gt;&lt;li&gt;Cabbage is ranked higher than Raisin Bran cereal&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;By ranking the foods based on a fixed calorie count, rather than on a realistic volume or weight basis, the Condé Nast list implies utterly terrible lifestyle advice.&amp;nbsp;It can't be that hard to figure out that foods like&amp;nbsp;&lt;a href="http://www.trueknowledge.com/q/fructose_in_cabbage"&gt;cabbage contribute a tiny amount of fructose to the diet&lt;/a&gt;. &amp;nbsp; People who rely upon SELF for nutritional information are not at all well-served by such a poorly designed guideline. Clearly, the folks over at Condé Nast aren't very serious about presenting good nutritional information to women.&lt;br /&gt;&lt;br /&gt;If I were &lt;a href="http://www.condenastdigital.com/about.html"&gt;Sarah Chubb&lt;/a&gt; (president of Condé Nast Digital) I'd order the nutrition site taken down immediately and replace the person who had editorial responsibility for it. &amp;nbsp;Chubb should find people who can reason quantitatively, and think about the content, not just about how it is presented.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6910739241883766195?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6910739241883766195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6910739241883766195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6910739241883766195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6910739241883766195'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/12/thinking-matters-even-in-conde-nast.html' title='Thinking matters, even in Condé Nast magazines'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-768792404388356978</id><published>2011-11-28T11:41:00.001-08:00</published><updated>2011-12-08T20:11:24.954-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Synecdoche'/><category scheme='http://www.blogger.com/atom/ns#' term='Autopoietic Systems'/><category scheme='http://www.blogger.com/atom/ns#' term='Autocatalysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Sustainability'/><title type='text'>Forgetful Filesystems</title><content type='html'>&lt;br /&gt;There is a slather of news and criticisms aimed at IBM for its &lt;a href="http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;amp;Sect2=HITOFF&amp;amp;p=1&amp;amp;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&amp;amp;r=1&amp;amp;f=G&amp;amp;l=50&amp;amp;co1=AND&amp;amp;d=PG01&amp;amp;s1=20110282838.PGNR.&amp;amp;OS=DN/20110282838RS=DN/20110282838"&gt;recently awarded patent application for a document aging file system&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm going to come to Big Blue's defense here, and say that it makes some sense in certain contexts. &lt;br /&gt;&lt;br /&gt;There is no such thing as a non-degrading media; digital storage simply reduces the error injection rate infinitesimal proportions and increases the rate at which refreshes occur by orders of magnitude. &amp;nbsp;Purposefully degrading the fidelity of the data stored on a system is a way to put the lifespan of the storage on par with the lifespan of pre-digital technologies, and thus be enabled to offer a similar value proposal.&lt;br /&gt;&lt;br /&gt;Individuals, businesses, and governments generate a lot of junk data. Should this junk data be treated with such high fidelity value as the stuff we really care about? &amp;nbsp;As long as we get to chose between what constitutes the good stuff and the junk, I'm all for having forgetful filesystems. &amp;nbsp;They are inevitable.&lt;br /&gt;&lt;br /&gt;There are a LOT of business and government records in particular that would be well placed into a round file. &amp;nbsp;I'm told that some of my tax records, for instance, should be kept around seven years. &amp;nbsp;Here is a way I can put such records, that to me are truly garbage, in a round file and know that eventually they'll be discarded just like paper copies, and the storage space can be reclaimed and sold to someone else.&lt;br /&gt;&lt;br /&gt;We couldn't save such junk data when the medium was paper, but why maintain it just because it went digital?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-768792404388356978?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/768792404388356978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=768792404388356978' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/768792404388356978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/768792404388356978'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/forgetful-filesystems.html' title='Forgetful Filesystems'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-350168117256216150</id><published>2011-11-27T17:56:00.001-08:00</published><updated>2011-11-27T19:17:58.746-08:00</updated><title type='text'>OSX Wireless Printing with Leftover PC printers</title><content type='html'>&lt;div&gt;Apple's AirPrint has very little in the way of direct vendor support. HP seemed to be the only printer maker that supports the protocol. &amp;nbsp;Now &lt;a href="http://epson.ipressroom.com/pr/epson/apple-s-airprint-wireless-printing-214701.aspx"&gt;Epson&lt;/a&gt;&amp;nbsp;and Cannon have joined in. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Epson printers suit me just fine. With an external inkwell, the cost of operation is a tiny fraction of the HP ink suckers. I have an older Epson though. What to do?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I dug up an old TrendNet TE100-P1U wireless print server. &amp;nbsp;The install manual claims that only PostScript printers are supported under OSX.&amp;nbsp;Not so!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just install the &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=1537&amp;amp;package_id=120183"&gt;Gimp Print CUPS drivers&lt;/a&gt;. You then add the print server as a printer under System Preferences, Scan and Print settings. Set the printer type to your printer's model (mine is an Epson 9400Fax). &amp;nbsp; Print a test page and... it worked! So now I can print from OSX wirelessly to my old PC printer, without the old PC. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No, as to AirPrint...&amp;nbsp;OSX Lion can act as a host to your IOS devices via &lt;a href="http://netputing.com/airprintactivator/airprint-activator-v2-0/"&gt;Activator 2.&lt;/a&gt;&amp;nbsp; It works fine sharing the print server printer, using the cups driver.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-350168117256216150?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/350168117256216150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=350168117256216150' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/350168117256216150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/350168117256216150'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/osx-wireless-printing-with-leftover-pc.html' title='OSX Wireless Printing with Leftover PC printers'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6934875718596058675</id><published>2011-11-21T06:39:00.001-08:00</published><updated>2011-12-07T19:59:29.670-08:00</updated><title type='text'>Textured Typeography with CSS3</title><content type='html'>Let's suppose I have a textual element that serves as a title and I don't want it to be a plain boring flat color. CSS3 has a nifty way of letting an image serve as a mask for an element.&lt;br /&gt;&lt;br /&gt;Let's take an image with some texture to it, say, the Lava effect from Gimp:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://mitch.amiano.agilemarkup.com/images/titlemask2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://mitch.amiano.agilemarkup.com/images/titlemask2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We can apply this to an element using the mask-image property:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;.title {&lt;br /&gt;&amp;nbsp;&amp;nbsp; -webkit-mask-image: &amp;nbsp;url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png);&amp;nbsp;&lt;br /&gt;  -o-mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png);&amp;nbsp;&lt;br /&gt; -moz-mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png);&amp;nbsp;&lt;br /&gt; mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png);&amp;nbsp;&lt;br/&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This gives us:&lt;br /&gt;&lt;h1 class="title" style="text-align: center;"&gt;Textured Text&lt;/h1&gt;Wherever the image mask is fully opaque, the original element content shows, and wherever it is fully transparent, the original element content is occluded. Between opaque and transparent, bits in the mask will show(or hide) content to the degree that they are partially opaque(or transparent). &lt;br /&gt;&lt;style&gt;code {  background-color: cream;  display: block;  position: relative;  margin-left: auto;  margin-right: auto;  width: 75%;}.title { font-family: sans-serif; font-weight: bold;font-size: 2cm;-webkit-mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png); -o-mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png); -moz-mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png); mask-image: url(http://mitch.amiano.agilemarkup.com/images/titlemask2.png); }&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6934875718596058675?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6934875718596058675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6934875718596058675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6934875718596058675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6934875718596058675'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/textured-typeography-with-css3.html' title='Textured Typeography with CSS3'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5178561845087808127</id><published>2011-11-19T20:34:00.001-08:00</published><updated>2011-11-21T20:24:13.838-08:00</updated><title type='text'>College Computer Science: We don't speak with LISP here.</title><content type='html'>A presenter at a conference was dismayed at how poorly the computers languages he was taught at NYU translated into practical application on the Web. I asked if LISP was among the languages. It wasn't.&lt;br /&gt;&lt;br /&gt;The look on some of the attendees' faces seemed to suggest I was being a wise-guy. I wasn't trying to be snarky; I expected his response because I'd heard it repeatedly and found through personal investigation of engineering curricula that it is not in the mainstream.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;λx.x&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Substitution of terms in expressions is a fundamental concept. It is so fundamental that kids who are allowed to handle money will do it intuitively when making change.&amp;nbsp;It is bizarre that such a fundamental hypothesis of calculation in computer science and mathematical logic is elided in modern computer science degree programs.&lt;br /&gt;&lt;br /&gt;(The same kids will run into difficulty reframing their experience, when given non-monetary challenges in math classes. They get counting and computing when it is informed by their&amp;nbsp;use of language; they lose the cognition when the language is removed. &amp;nbsp;So add the vocabulary and operators of substitution to their&amp;nbsp;repertoire&amp;nbsp;, early, often, and concretely, and perhaps they will actually start intuiting what computation is all about.)&lt;br /&gt;&lt;br /&gt;To the best of my recollection the first standardized transformation language for markup content was ISO/IEC 10179:1996 (DSSSL). It used a subset of Scheme (a LISP dialect) and in turn informed the development of XSL(T). Functional languages (Javascript is another example) are excellent tools for processing markup. University educators need to get beyond their own reframing difficulty to recognize the obvious substitution of "markup" for "Web," and Scheme to re-introduce a little more of a LISP in their discourse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5178561845087808127?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5178561845087808127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5178561845087808127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5178561845087808127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5178561845087808127'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/college-computer-science-we-dont-speak.html' title='College Computer Science: We don&apos;t speak with LISP here.'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-548171000209173165</id><published>2011-11-17T07:04:00.001-08:00</published><updated>2011-11-17T07:41:28.783-08:00</updated><title type='text'>Emotional Maturity and Divorce</title><content type='html'>My spouse has been married to me for over 25 years. The relationship is symmetric: I've been married to her for precisely the same amount of time. It certainly isn't reflexive: we're may be married to each other but I'm not married to myself. &amp;nbsp;And it isn't transitive either; if I was married to someone else, that wouldn't mean that my two wives would be married (and anyway that would be bigamy). Therefore:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;div class="Apple-style-span" style="background-color: rgba(55,55,250, 0.5); border-radius: 5px; font-family: Verdana, sans-serif; font-size: x-large; padding-bottom: 3.25em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 2.5em;"&gt;Marriage is Not An Equivalence Relation&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Look, I'm not bragging about it. &amp;nbsp; I'm no more worthy of accolades on this matter than any one of my divorced friends and relatives. &amp;nbsp;Life has not always a bed of roses either; &amp;nbsp;just as in the economy, &amp;nbsp;externalities shift and expectations change, &amp;nbsp;excitement can give way to&amp;nbsp;disappointment, disappointment to grief, and new realities set in. &amp;nbsp;But in our 25 years of marriage, we've been witness to a great deal of divorce, which substantively impacted our family and relationships.&lt;br /&gt;&lt;br /&gt;No matter how close you imagine yourself to be to someone, you're not that person and they are not you. The unity is plural. Perceptions matter a little, to be sure, but having a good grasp of reality and an emotional balance between empathy and self-interest matters much more. That means taking time to be reflective together, actively exercising empathy and not just entertaining yourselves on a date night and slugging through chores the rest of your time. Or in the case of those struggling with a loss or divorce, &lt;a href="http://www.divorcepeers.com/dating-after-divorce-wait.htm"&gt;taking a year off to normalize your emotional response to relationships&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-548171000209173165?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/548171000209173165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=548171000209173165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/548171000209173165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/548171000209173165'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/emotional-maturity-and-divorce.html' title='Emotional Maturity and Divorce'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7497206755792377387</id><published>2011-11-16T11:20:00.001-08:00</published><updated>2011-11-16T15:33:32.419-08:00</updated><title type='text'>The Pakled Philosophy of Development</title><content type='html'>&lt;div&gt;A rambling, opinionated, and very poorly justified rant. Please don't shoot me, I'm just venting.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;A few months ago I blogged on my &lt;a href="http://www.unityisplural.com/2011/09/why-i-dislike-php.html"&gt;disenchantment with PHP&lt;/a&gt;. &amp;nbsp;It isn't just PHP, but Java, Perl, and ASP/.NET that make me feel similarly estranged.&amp;nbsp;&amp;nbsp;The thing is, I want to work with languages, platforms, and systems that don't really, truly, deeply suck, on projects that are worth doing. &amp;nbsp;Sadly, that's a rare combination.&amp;nbsp;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;I'm not sure exactly what it is about server-pages platforms that gives rise to such feelings of discomfort. I've worked with Joomla and Drupal and ASP sites, so perhaps it is in part the layering of immature cultural cruft inherent in their codebases that gives me the stray thoughts of "what a freakin' mess," and "are you kidding me?" &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But as convoluted as some poorly written components can be, it isn't the primary reason these platforms suck. They suck because, for a dollar you put in today, you have to put a dollar plus change more in tomorrow just to keep the stack from completely collapsing in on itself. &amp;nbsp;In effect, these platforms encourage a kind of codebase Ponzi scheme or a development Hell.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0Tt0OvdVrd0/TsQVzQZE1RI/AAAAAAAAADQ/W50VRaPU1_Q/s1600/pakled04.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-0Tt0OvdVrd0/TsQVzQZE1RI/AAAAAAAAADQ/W50VRaPU1_Q/s320/pakled04.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;"We look for things."&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All development builds upon previously constructed artifacts. Those artifacts must be available, demonstrably functional, and comprehendible to contribute to the next generation. &amp;nbsp;Our objectives should not be merely to "make things go", but should include incorporating our knowledge into our archetypal forms, a process of language refinement. &amp;nbsp;With PHP, Java, and so many other languages, we focus our efforts on entraining more and more information into the platforms, like some sort of junk DNA as it were; the languages and libraries grow in complexity much faster than they grow in value. Similarly, artifacts in these languages seem to have a very limited impact in advancing the system to higher levels of functionality.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Web Developers using server-page approaches produce piecemeal patchworks of solutions that last for a few months to a few years. Do such systems get increasingly easier to understand and maintain, or do they get increasingly cluttered and ever more risk laden? &amp;nbsp;Is there repeatability, refinement, increasing transparency, and data unencumbered by private licensing, or a daily slog of Development Hell?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PHP systems rarely gain&amp;nbsp;the level of maturity needed to be approach either self-consistency or completeness and closure over a domain. &amp;nbsp;The intelligent fall-back position when you're ignorant is Lean -- sacrifice completeness and reduce the feature set to that which is minimally viable. Focus on what provides value. But if you just want to make it go, Pakled style, even when provided sufficient resources it won't contribute to the process of exposing and refining the domain language. Developing a domain language to incorporate new knowledge simply isn't a value proposition that is often pursued in that development culture, and it isn't well supported by the language.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In mathematics, there is the concept of the derivative. In the context of a function that plots a curve, the derivative tells you the rate at which the function output values are changing at a given point on the curve: it tells you the slope, as it were. &amp;nbsp;&amp;nbsp;In order for solutions to remain viable over time, the slope of the curve of revenue generating features must be greater than the slope of the curve of hidden costs and intangible liabilities. &amp;nbsp;Otherwise, you're creating a shell hollowed out of real value. &amp;nbsp;My sense on server page technologies is that feature incorporation has a relatively flat slope, the cost curve increases more rapidly, and hidden liabilities arise very abruptly and without warning.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For most clients of technology, it is a lose-lose proposition: they know they need to spend the money to stay in the game, but the game is rigged with goods frequently subject to erratic and unplanned obsolescence.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But that begs two questions. Are there any more sustainable alternatives? Would a more sustainable alternative slow down the pace of innovation? I don't pretend to know the answers but after blathering on in this article, I at least understand some of the reasons why languages like PHP rub me the wrong way.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7497206755792377387?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7497206755792377387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7497206755792377387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7497206755792377387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7497206755792377387'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/pakled-philosophy-of-development.html' title='The Pakled Philosophy of Development'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-0Tt0OvdVrd0/TsQVzQZE1RI/AAAAAAAAADQ/W50VRaPU1_Q/s72-c/pakled04.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-9080997874319813439</id><published>2011-11-14T06:49:00.001-08:00</published><updated>2011-11-14T06:57:18.114-08:00</updated><title type='text'>Groan! Sass is great, but incomplete</title><content type='html'>&lt;br /&gt;Seduced by the lure of smaller, cleaner, neater, and more responsive stylesheets, I began moving my &lt;a href="http://mitch.amiano.agilemarkup.com/"&gt;home page&lt;/a&gt; to Compass and SASS. &amp;nbsp;I installed compass, and got the basic framework in place quickly.&lt;br /&gt;&lt;br /&gt;Then I went away for a while.&lt;br /&gt;&lt;br /&gt;When I came back, it was because I had the brilliant idea to clean up the media selectors I had made a mess of. "Variables," I thought, "Why, SASS' variable interpolation would make that much easier!"&lt;br /&gt;&lt;br /&gt;Sadly, this is not yet the case as of version 3.1.10 :&lt;br /&gt;&lt;br /&gt;Syntax error: Invalid CSS after "(max-width: ": expected expression (e.g. 1px, bold), was "$phone-height) {"&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; on line 33 of /Users/mamiano/workspace/mitch.amiano.agilemarkup.com/sass/screen.scss&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; from line 1 of /Users/mamiano/workspace/mitch.amiano.agilemarkup.com/sass/index.scss&lt;br /&gt;&lt;br /&gt;Backtrace:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, they are pushing to fix it in version 3.2. &amp;nbsp;The thought occurs to me that for simple cases, a regexp replacement could do the trick if it could be inserted before Compass processed the file through SASS.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-9080997874319813439?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/9080997874319813439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=9080997874319813439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/9080997874319813439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/9080997874319813439'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/groan-sass-is-great-but-incomplete.html' title='Groan! Sass is great, but incomplete'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5791861514241540916</id><published>2011-11-13T07:22:00.001-08:00</published><updated>2011-11-18T19:49:08.178-08:00</updated><title type='text'>Getting fuse4x installed on OSX Lion</title><content type='html'>&lt;style&gt;code {   display: block;  padding: 1em;  margin: 1em;  background: rgba(55,55,55,0.125);  border-radius: 5px;  box-shadow: 5px 5px 10px 0px rgba(0, 0, 0, 1);&lt;/style&gt;&lt;br /&gt;I tried out Fuse4x and sshfs for OSX, through Hombrew, this week-end. It should have been a piece of cake, but apparently the recipes aren't very good about telling when another fuse package is installed.&lt;br /&gt;&lt;br /&gt;As recommended, I did the install:&lt;br /&gt;&lt;code&gt;$ brew install fuse4x sshfs&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Homebrew cheerfully informs me that sshfs won't work unless I sudo copy a file, so I follow its instructions. Seems a bit strange to have to do this manually:&lt;br /&gt;&lt;code&gt;$ sudo cp -rfX /usr/local/Cellar/fuse4x-kext/0.8.13/Library/Extensions/fuse4x.kext /System/Library/Extensions&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$ sudo chmod +s /System/Library/Extensions/fuse4x.kext/Support/load_fuse4x&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Alas, things just didn't work:&lt;br /&gt;&lt;code&gt;$ sshfs myname@mysite.me: &amp;nbsp;~/mnt/mysite.me&lt;br /&gt;/Library/Filesystems/fusefs.fs/Support/fusefs.kext failed to load - (libkern/kext) link error; check the system/kernel logs for errors or try kextutil(8).&lt;br /&gt;the MacFUSE file system is not available (71)&lt;/code&gt;&lt;br /&gt;Well, actually, it looks like the kernel extension never even loaded. &amp;nbsp;OSX is supposed to attempt to auto-load them when a fuse filesystem is mounted, but it doesn't look like it succeeded. I use kextunload and kextload to get it to load the extensions:&lt;br /&gt;&lt;code&gt;$ kextunload&amp;nbsp;/System/Library/Extensions/fuse4x.kext/&lt;br /&gt;&lt;br /&gt;(kernel) Kext org.fuse4x.kext.fuse4x not found for unload request.&lt;br /&gt;Failed to unload org.fuse4x.kext.fuse4x - (libkern/kext) not found.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;$ kextload&amp;nbsp;/System/Library/Extensions/fuse4x.kext/&lt;/code&gt;&lt;br /&gt;Yet trying sshfs again gives the same error. What gives?&lt;br /&gt;&lt;br /&gt;I look for more info on homebrew and fuse4x forums and bug lists.&amp;nbsp;Wading through Web pages -- they all describing the solution to the link error as (to sum up) "use fuse4x". &amp;nbsp;I *am* using fuse4x. One &lt;a href="https://github.com/mxcl/homebrew/issues/8224"&gt;bug report&lt;/a&gt; on homebrew hinted at a possible cause to the problem.&lt;br /&gt;&lt;br /&gt;It looks like at some point, I had a MacFuse installed, &amp;nbsp;and it left an orphaned copy of /usr/local/lib/pkgconfig/fuse.pc:&lt;br /&gt;&lt;code&gt;$ cat /usr/local/lib/pkgconfig/fuse.pc&lt;br /&gt;prefix=/usr/local&lt;br /&gt;exec_prefix=${prefix}&lt;br /&gt;libdir=${exec_prefix}/lib&lt;br /&gt;includedir=${prefix}/include&lt;br /&gt;&lt;br /&gt;Name: fuse&lt;br /&gt;Description: File System in User Space (MacFUSE)&lt;br /&gt;Version: 2.7.3&lt;br /&gt;Libs: -L${libdir} -lfuse -pthread &amp;nbsp;-liconv&lt;br /&gt;Cflags: -I${includedir}/fuse -D__FreeBSD__=10 -D_FILE_OFFSET_BITS=64&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;So I brew uninstall fuse4x, remove the fuse.pc file, and brew install fuse4x.&lt;br /&gt;The homebrew recipe symlinked to the correct fuse.pc file, and I hoped all was good.&lt;br /&gt;&lt;br /&gt;It was not good. Same error. &amp;nbsp;I check the system kernel error logs:&lt;br /&gt;&lt;code&gt;&amp;nbsp;kernel[0]: fuse4x: starting (version 0.8.13, Nov 11 2011, 17:54:24)&lt;br /&gt;&amp;nbsp;kernel[0]: kxld[com.google.filesystems.fusefs]: The following symbols are unresolved for this kext:&lt;br /&gt;&amp;nbsp;kernel[0]: kxld[com.google.filesystems.fusefs]: &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;_OSRuntimeFinalizeCPP&lt;br /&gt;&amp;nbsp;kernel[0]: kxld[com.google.filesystems.fusefs]: &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;_OSRuntimeInitializeCPP&lt;br /&gt;&amp;nbsp;kernel[0]: Can't load kext com.google.filesystems.fusefs - link failed.&lt;br /&gt;&amp;nbsp;kernel[0]: Failed to load executable for kext com.google.filesystems.fusefs.&lt;br /&gt;&amp;nbsp;kernel[0]: Kext com.google.filesystems.fusefs failed to load (0xdc008016).&lt;br /&gt;&amp;nbsp;kernel[0]: Failed to load kext com.google.filesystems.fusefs (error 0xdc008016).&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Egads! Unresolved symbols? Something just isn't right. &amp;nbsp;Looks like the same 32 bit MacFuse garbage.&lt;br /&gt;&lt;br /&gt;At this point, I'm seriously doubting the sanity of the the homebrew fuse4x/sshfs recipes. Maybe someone thought they were working, as a coincidence of them already having a working fuse4x kernel extension installed.&lt;br /&gt;&lt;br /&gt;Well, it turns out that the MacFuse code was not fully uninstalled, and the brew recipe simply accepts the existing files without complaint or comment:&lt;br /&gt;&lt;code&gt;$ ls -ld /Library/Filesystems/fusefs.fs&lt;br /&gt;drwxr-xr-x &amp;nbsp;4 root &amp;nbsp;wheel &amp;nbsp;136 Dec 19 &amp;nbsp;2008 /Library/Filesystems/fusefs.fs&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;div&gt;December of 2008 ???! &amp;nbsp;That's a little dated for a filesystem I installed today (Nov 2011). Even if it were unzipped from a file (which it wasn't), the datestamps of an active project should be more recent than 2008.&lt;/div&gt;&lt;br /&gt;My experience with the fuse4x recipe is that it doesn't do squat for detecting previously installed files.... it just accepts them without complaint.&lt;br /&gt;&lt;br /&gt;If you've got a previous install of anything remotely resembling MacFuse, clear it out, clean it out, and purge every remnant from your system before monkeying around with fuse4x.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ /Library/Filesystems/fusefs.fs/Support/uninstall-macfuse-core.sh&lt;br /&gt;&lt;br /&gt;MacFUSE Uninstaller: Sudoing...&lt;br /&gt;Password:&lt;br /&gt;MacFUSE Uninstaller: Can not find the Archive.bom for MacFUSE Core package.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Alas, if you upgraded to OSX Lion and MacFuse was previously installed, a LOT of garbage was left around. Kind of makes you wonder, why Apple still has no package management system, but I digress...&lt;/div&gt;&lt;div&gt;&lt;code&gt;$ brew uninstall fuse4x&lt;br /&gt;$ brew uninstall sshfs&lt;br /&gt;$ rm -rf &amp;nbsp;/usr/local/include/fuse&lt;br /&gt;$ rm /usr/local/lib/libfuse_*&lt;br /&gt;$ sudo rm -rf /Library/Filesystems/fusefs.fs&lt;br /&gt;$ sudo rm -rf /System/Library/Extensions/fuse4x.kext/&lt;/code&gt;&lt;/div&gt;&lt;div&gt;Hopefully, I'm not clobbering anything too important that actually worked before now. &amp;nbsp;I check for anything else fuse related:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;code&gt;$ find / -name "*fuse*" -print&lt;br /&gt;/Applications/Custom/expandrivencsu/ExpanDrive.app/Contents/ExpanDrive/fs/fstools/fuse.pyo&lt;br /&gt;/Applications/Custom/expandrivencsu/ExpanDrive.app/Contents/Resources/com.expandrive.ExpanDrive.exfs.components/libfuse.dylib&lt;br /&gt;/private/var/db/receipts/com.google.macfuse.bom&lt;br /&gt;/private/var/db/receipts/com.google.macfuse.core.bom&lt;br /&gt;/private/var/db/receipts/com.google.macfuse.core.plist&lt;br /&gt;/private/var/db/receipts/com.google.macfuse.plist&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;AHA! That explains where my MacFuse install came from! It was a stowaway on a tool I had used to support a client project! &amp;nbsp;Well, expandrive can be trashed with CleanApp. I plug the com.google.macfuse receipts as well:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;code&gt;$ sudo rm /private/var/db/receipts/com.google.macfuse.bom&lt;br /&gt;$ sudo rm /private/var/db/receipts/com.google.macfuse.core.bom&lt;br /&gt;$ sudo rm /private/var/db/receipts/com.google.macfuse.core.plist&lt;br /&gt;$ sudo rm /private/var/db/receipts/com.google.macfuse.plist&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;OK. Time to start over.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;code&gt;$ brew install fuse4x&lt;br /&gt;==&amp;gt; Cloning https://github.com/fuse4x/fuse.git&lt;br /&gt;Updating /Users/myname/Library/Caches/Homebrew/fuse4x--git&lt;br /&gt;==&amp;gt; Checking out tag fuse4x_0_8_13&lt;br /&gt;==&amp;gt; autoreconf --force --install&lt;br /&gt;==&amp;gt; ./configure --disable-debug --disable-static --prefix=/usr/local/Cellar/fuse4x/0.8.13&lt;br /&gt;==&amp;gt; make install&lt;br /&gt;/usr/local/Cellar/fuse4x/0.8.13: 16 files, 728K, built in 35 seconds&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;$ brew install sshfs&lt;br /&gt;==&amp;gt; Cloning https://github.com/fuse4x/sshfs.git&lt;br /&gt;Updating /Users/myname/Library/Caches/Homebrew/sshfs--git&lt;br /&gt;==&amp;gt; Checking out tag sshfs_2_3_0&lt;br /&gt;==&amp;gt; autoreconf --force --install&lt;br /&gt;==&amp;gt; ./configure --disable-debug --prefix=/usr/local/Cellar/sshfs/2.3.0&lt;br /&gt;==&amp;gt; make install&lt;br /&gt;==&amp;gt; Caveats&lt;br /&gt;Make sure to follow the directions given by `brew info fuse4x-kext`before trying to use a FUSE-based filesystem.&lt;br /&gt;==&amp;gt; Summary&lt;br /&gt;/usr/local/Cellar/sshfs/2.3.0: 6 files, 116K, built in 10 seconds&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;$ brew info fuse4x-kext&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;div&gt;fuse4x-kext 0.8.13&lt;/div&gt;&lt;div&gt;http://fuse4x.org/&lt;/div&gt;&lt;div&gt;/usr/local/Cellar/fuse4x-kext/0.8.13 (5 files, 304K)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order for FUSE-based filesystems to work, the fuse4x kernel extension&lt;/div&gt;&lt;div&gt;must be installed by the root user:&lt;/div&gt;&lt;div&gt;&amp;nbsp; sudo cp -rfX /usr/local/Cellar/fuse4x-kext/0.8.13/Library/Extensions/fuse4x.kext /System/Library/Extensions&lt;/div&gt;&lt;div&gt;&amp;nbsp; sudo chmod +s /System/Library/Extensions/fuse4x.kext/Support/load_fuse4x&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;http://github.com/mxcl/homebrew/commits/master/Library/Formula/fuse4x-kext.rb&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;$ sudo cp -rfX /usr/local/Cellar/fuse4x-kext/0.8.13/Library/Extensions/fuse4x.kext /System/Library/Extensions&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;$ sudo chmod +s /System/Library/Extensions/fuse4x.kext/Support/load_fuse4x&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;$ sshfs myname@mysite.me: &amp;nbsp;~/mnt/mysite.me&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally! Everything just worked! Satisfaction!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5791861514241540916?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5791861514241540916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5791861514241540916' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5791861514241540916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5791861514241540916'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/getting-fuse4x-installed-on-osx-lion.html' title='Getting fuse4x installed on OSX Lion'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-633557311705645894</id><published>2011-11-09T09:39:00.000-08:00</published><updated>2011-11-09T09:43:19.801-08:00</updated><title type='text'>Going to Compass</title><content type='html'>A new home page for me, myself, and I, is posted at &lt;a href="http://mitch.amiano.agilemarkup.com/"&gt;http://mitch.amiano.agilemarkup.com&lt;/a&gt;&amp;nbsp;.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After playing with some ideas about a canvas toy and Javascript managed page, I decided to stop screwing around with it. There is still a "play" page, for silly toys, but the rest of the site&amp;nbsp;uses good-old, straightforward HTML5 content and CSS3.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The intent wasn't to do anything too flashy (as if I'm capable of being that flashy), but to at least show off some of the technologies I use or have used, and to put out a general call to action (hire me!)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After putting up a few more pages I realized I'd be wasting a lot of time futzing around with the CSS rules. The problem isn't one of mere file organization, but of the brutally redundant information spread among the style rules themselves, and the interdependencies among the rules.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A common software technique for managing increasing complexity is to modularize. Yet CSS provides no meaningful modularization mechanisms. &amp;nbsp;Splitting style rules into separate .css files is a trivial, almost valueless, proposition, because the cost of keeping up with which rule is (or is not, or should be, or should not be) in which file overwhelms any benefit from separating the rules appropriate to each page. &amp;nbsp;The problem of repetition of&amp;nbsp;semantic-less constants and interaction among rules also still remains. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Managing style rules as CSS syntax in files, even with an IDE, is a waste of time. Yes, people pay for it, but it is still time wasted. We can be cleverer than that.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://compass-style.org/"&gt;Compass&lt;/a&gt;, or more precisely, SASS, provides a meaningful modularization and refactoring syntax layer. SASS is a kind of algebra for CSS, allowing you to identify patterns and factor out common variables. Compass is the tool that makes it feasible to use.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First step: get Ruby. Since OSX runs my development machine, and I use RVM to manage the scripting engines and gem components for development, I've already got Ruby. But I do need to chose which Ruby and gemset I'll use:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;cd ~/workspace/mitch.amiano.agilemarkup.com&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;rvm gemset create agilemarkup&lt;br /&gt;echo "rvm use ruby-1.9.2@agilemarkup" &amp;gt;.rvmrc&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Next step: get Compass. I tend not to like it when components for one project pollutes another project, and hate the hassle of manually figuring out component dependencies, so I'm going to use Bundler to make the gem dependency explicit:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cat &amp;lt;&lt;eot&gt; Gemfile&lt;br /&gt;source 'http://rubygems.org' &lt;br /&gt;gem 'compass' &lt;br /&gt;EOT&lt;br /&gt;bundle&lt;/eot&gt;&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Running bundle will fetch the Compass gem and any other gem component dependencies needed to use Compas' features.&lt;br /&gt;&lt;br /&gt;Now, Gemfile and .rvmrc are specifications of the toolchain that supports the publishing process. Those are pretty&amp;nbsp;high value bits, so they should be version controlled. I use GIT, so yeah, that's easy:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;echo "Gemfile.lock" &amp;gt;&amp;gt; .gitignore&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;git add Gemfile .rvmrc .gitignore&lt;/span&gt;&lt;eot style="font-family: monospace;"&gt;&lt;br /&gt;git commit -m "add Compass to manage stylesheets"&lt;/eot&gt;&lt;br /&gt;&lt;br /&gt;The Compass gem installed, it is time to set up the basic framework of files in the working tree:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;cd ..&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;compass create mitch.amiano.agilemarkup.com&lt;/span&gt;&lt;eot style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/eot&gt;&lt;br /&gt;&lt;code&gt;&lt;eot style="font-family: monospace;"&gt;cd mitch.amiano.agilemarkup.com&lt;/eot&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There is a load of stuff created:&lt;br /&gt;&lt;pre&gt;directory mitch.amiano.agilemarkup.com/sass/&lt;br /&gt;directory mitch.amiano.agilemarkup.com/stylesheets/&lt;br /&gt;   create mitch.amiano.agilemarkup.com/config.rb &lt;br /&gt;   create mitch.amiano.agilemarkup.com/sass/screen.scss &lt;br /&gt;   create mitch.amiano.agilemarkup.com/sass/print.scss &lt;br /&gt;   create mitch.amiano.agilemarkup.com/sass/ie.scss &lt;br /&gt;   create mitch.amiano.agilemarkup.com/stylesheets/ie.css &lt;br /&gt;   create mitch.amiano.agilemarkup.com/stylesheets/print.css &lt;br /&gt;   create mitch.amiano.agilemarkup.com/stylesheets/screen.css &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, get Compass to watch the directories and process any SASS files that change:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;code&gt;compass watch &amp;amp;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That's it! I'm all set for refactoring my stylesheets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-633557311705645894?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/633557311705645894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=633557311705645894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/633557311705645894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/633557311705645894'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/11/going-to-compass.html' title='Going to Compass'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8497145155134947341</id><published>2011-10-24T08:47:00.000-07:00</published><updated>2011-11-09T08:25:09.135-08:00</updated><title type='text'>When a UI is too smart for our own good</title><content type='html'>I'm tearing my hair out at Apple's latest user experience faux pas: gestures on the desktop.&lt;br /&gt;&lt;br /&gt;Now, they seem really cool at first. But a few of the gestures really interfere with my experience in incredibly painful ways.&lt;br /&gt;&lt;br /&gt;The most painful so far, is the idiotic choice to make a rightward swipe equivalent to the Back button on the browser. This is such a completely brain dead idea that&amp;nbsp;it actually makes me question the competence of Apple's UI team.&lt;br /&gt;&lt;br /&gt;Years ago, some other patronizing UI designer decided to make the Backspace key an alternative trigger for the Back button action. The overloaded behavior meant that countless almost-completed forms were at risk of being wiped away by an obvious response to a typo.&lt;br /&gt;&lt;br /&gt;Yes, there are programmatic workarounds, but they shouldn't be needed. Backspace-As-Navigation-Button is a potentially destructive action tied to a control that has a completely different function, and that is&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #cc0000; font-size: x-large; letter-spacing: 0.6em;"&gt;JUST&amp;nbsp;PLAIN&amp;nbsp;WRONG&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Apple not only did not learn the lesson that overloading controls is a really bad thing to do, it copied this &amp;nbsp;egregious example of pathological UI design and made it worse by tying it to leftward scrolling.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Fortunately, Apple does give the ability to turn off the gestures. Just go into System Preferences, into the Trackpad settings, and choose More Gestures. Uncheck the Swipe between pages checkbox, and your experience in browser forms will be much less problematic. &amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8497145155134947341?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8497145155134947341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8497145155134947341' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8497145155134947341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8497145155134947341'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/10/when-ui-is-too-smart-for-our-own-good.html' title='When a UI is too smart for our own good'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-648287628871154114</id><published>2011-10-05T09:43:00.000-07:00</published><updated>2011-10-05T09:43:10.361-07:00</updated><title type='text'>Mac Marginalia</title><content type='html'>I'm fiddling with getting my resume up on my Web site, and getting diverted by sundry tweaks. &lt;br /&gt;&lt;div&gt;Might as well note the tweaks here, as they seem to be handy.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-hyqyn4ekg54/ToxvRVn8_0I/AAAAAAAAAB8/4062FS2OaQg/s1600/PICT0028.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-hyqyn4ekg54/ToxvRVn8_0I/AAAAAAAAAB8/4062FS2OaQg/s320/PICT0028.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;This Picture Has Nothing to do with the post.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;The resume is kept in a git repository. The repos are all kept under ~/workspace (and sometimes mirrored to GitHub, Dropbox and/or pushed to the Web.)&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Problem:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Dropbox appears in the Finder "Favorites" sidebar, but ~/workspace does not.&amp;nbsp;&lt;/li&gt;&lt;li&gt;So I go looking for it repeatedly.&amp;nbsp;&lt;/li&gt;&lt;li&gt;That's annoying. What to do?&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Solution:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Open a Finder window.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Navigate to ~/workspace.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Press &lt;b&gt;Command-T&lt;/b&gt; to add ~/workspace to the Favorites list.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;hr width="30%" /&gt;&lt;/div&gt;&lt;div&gt;Problem:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;git status&lt;/b&gt;&amp;nbsp;in a terminal shell window at ~/workspace/resume reveals a .DS_Store file.&lt;/li&gt;&lt;li&gt;Mac OSX pollutes folders with .DS_Store files to hold Finder information. Call 'em lazy.&amp;nbsp;&lt;/li&gt;&lt;li&gt;That file doesn't belong in the repo. That's annoying. What to do?&lt;/li&gt;&lt;li&gt;If you remove the file, it will just come back. That's annoying. What to do?&lt;/li&gt;&lt;/ul&gt;Solution:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Go to the terminal shell at ~/workspace/resume&amp;nbsp;&lt;/li&gt;&lt;li&gt;echo '*.DS_Store' &amp;gt;&amp;gt; ~/.gitignore_global&amp;nbsp;&lt;/li&gt;&lt;li&gt;git config --global core.excludesfile ~/.gitignore_global&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;hr width="30%" /&gt;&lt;/div&gt;&lt;div&gt;Problem:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-648287628871154114?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/648287628871154114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=648287628871154114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/648287628871154114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/648287628871154114'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/10/mac-marginalia.html' title='Mac Marginalia'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-hyqyn4ekg54/ToxvRVn8_0I/AAAAAAAAAB8/4062FS2OaQg/s72-c/PICT0028.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7395808202607394785</id><published>2011-09-27T16:18:00.000-07:00</published><updated>2011-09-27T20:59:41.447-07:00</updated><title type='text'>"Opinionated" as a Professional Practice</title><content type='html'>I hear programmers tossing the word "opinionated" around a lot these days. &lt;div&gt;Usually, it is used to characterize a development library or framework, as in, &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;Rails is an Opinionated Framework&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So why is it that "opinionated" also seems to be used as a euphemism for hard-coding, discrete variables and subroutines, avoidance of data-driven process, or otherwise representing decisions as fixed structures in the code?  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An old rule of thumb in engineering is, that the earlier in the fabrication that decisions are fixed, the deeper and more wide-spread is the impact. Regardless of the decision's impact as a cost saving or increase, making a decision early causes a cascade of ripples throughout the system. That's the trouble with being too opinionated: you have already made decisions prejudicially. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Researchers of old used to say that you should build one (or two) to throw away.  Perhaps the tendency of programmers to be too opinionated is why. Perhaps it is also why so much of today's hot newest Web coding technologies appear to be legacy code before they even get released.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7395808202607394785?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7395808202607394785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7395808202607394785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7395808202607394785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7395808202607394785'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/opinionated-as-professional-practice.html' title='&quot;Opinionated&quot; as a Professional Practice'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5573235364220228310</id><published>2011-09-27T09:23:00.000-07:00</published><updated>2011-11-09T08:33:29.043-08:00</updated><title type='text'>MacOS X Lion XCode 4 madness</title><content type='html'>Ah, I'm going utterly insane with frustration. After sitting down two hours ago to start doing some coding, I found that my upgraded Lion system with Xcode 4 has a mysteriously broken command terminal:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;MacBook-Pro:~ user$ clear                                                             &lt;br /&gt;terminals database is inaccessible&lt;/code&gt;&lt;/div&gt;&lt;div&gt;Wha ???&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, if you go looking at forums, a lot of them are going to say something like "check your TERM" or "try removing your dot files temporarily", or some such. That's misdirection, based on someone hacking together a Linux environment. This is OSX, and I haven't been hacking my environment recently. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Seems that either the Lion upgrade or Xcode 4 screwed something up. An &lt;a href="http://stackoverflow.com/questions/6788402/error-opening-terminal-xterm-256color"&gt;Ubuntu posting on Stack Overflow&lt;/a&gt; discusses the cause of the problem, a missing terminfo file (/usr/share/terminfo/78/xterm-256color). I go into Time Machine to investigate, and lo and behold, there is no /usr. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="background-color: black; font-family: Georgia, 'Times New Roman', serif; font-size: x-large; padding-bottom: 1em; padding-left: 1em; padding-right: 1em; padding-top: 1em;"&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;#&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #444444;"&gt;$&lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;@&lt;/span&gt;&lt;span class="Apple-style-span" style="color: yellow;"&gt;@&lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;$&lt;/span&gt;&lt;span class="Apple-style-span" style="color: lime;"&gt;%&lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;@&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;$&lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;!!!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Mac OSX apparently hides UNIX files. Where's the UI setting for that? Um, well, the folks at Apple decided that magically hiding files should be managed by a magical switch:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;MacBook-Pro:~ user$  defaults write com.apple.finder AppleShowAllFiles True&lt;br /&gt;MacBook-Pro:~ user$ killall Finder&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;div&gt;(Really, Apple? Why is there no UI? The &lt;a href="http://developer.apple.com/library/mac/#documentation/darwin/reference/manpages/man1/defaults.1.html"&gt;man page detritus&lt;/a&gt; has no indication of what the actual settings are. So much for UI discoverability, but at least &lt;a href="http://www.macosxtips.co.uk/index_files/terminal-commands-for-hidden-settings-in-leopard.php"&gt;some of the info&lt;/a&gt; is &lt;a href="http://hints.macworld.com/article.php?story=200812240619357"&gt;documented&lt;/a&gt;, and thanks to Google and places like Stack Overflow it can be found.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I go to restore the file, finding it a couple of weeks back. Unfortunately, Time Machine still won't show UNIX directories in its file browser. The original location (/usr/share/terminfo/78) isn't visible as an option. I copy it manually. Stupid.Magical.Finder. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note to the person on the Xcode 4 team that decided to do the cleaning up: multiply the time wasted that by all the developers you tripped up, and your one mistake probably comes out to hundreds of hours, not to mention the systems that now have crippled terminfo files. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5573235364220228310?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5573235364220228310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5573235364220228310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5573235364220228310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5573235364220228310'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/macos-x-lion-xcode-4-madness.html' title='MacOS X Lion XCode 4 madness'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3942386310914770230</id><published>2011-09-22T08:08:00.001-07:00</published><updated>2011-09-22T14:30:39.972-07:00</updated><title type='text'>Nokahuna and That Other task manager</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;The name of that other task manager is Trello. Even though the name is forgettable, it offers some interesting features. Things like auto-updating, and a very strong visual metaphor.&lt;br /&gt;&lt;br /&gt;In contrast, Nokahuna has a kind of 1950s style - the pastel lime green made me think of the worn out Formica of some old diner out in the middle of some old, mostly abandoned downtown.&lt;br /&gt;&lt;br /&gt;To be fair, Trello isn't visually stunning itself. But it does offer a more chunky version of the todo list. The metaphor is one of pinup boards with cards stuck to them, and highlighter colors used for labeling. It is not an unpleasant departure from the creamy, everything-runs-together-until-your-eyes-bleed shtick that dominates almost every project management system and todo list manager under the sun.&lt;br /&gt;&lt;br /&gt;Unfortunately, in it's current incarnation Trello doesn't work well on my iPad2. There was a "transport unavailable" error on every page... I doubt that the auto-updating feature works as expected... And whatever they did to code up the browser UI, it has jerked up the touch events to the point that every action requires at least two touchdowns to register one.Some things that were pointed out in the welcome board simply did not work, like Drag and drop, or the elusive user manual (um, where is it exactly?)&lt;br /&gt;&lt;br /&gt;That brings me to the last feature that seems to be missing: the ability to delete your account. Trello doesn't give you that option. It seems that some users adopted the practice of appending "delete" to their screen names. Maybe that is in the missing manual.&lt;br /&gt;&lt;br /&gt;So I turn my attention to Nokahuna. First issue up: the welcome screen offers me (an iPad2 user) to view a Flash based screen cast. Not exactly the best first impression.&lt;br /&gt;&lt;br /&gt;The rest of Nokahuna reaffirms my initial style impressions.... This _is_ an old dive. There are no frills in Nokahuna, and for the most art that is a good thing. It is a task list manager, and that is it. Teams with fixed functional roles for people may find the minimalism a little too simple, but I can see the appeal to Agile folks who collaborate as independents or in a tiny cross-functional team.&lt;br /&gt;&lt;br /&gt;For visual metaphors, Nokahuna is much weaker than Trello. It is unremarkable  and like a dozen other tiny todo list tools I've seen, hacked, or used in the past 20 years. This isn't a remark about the minimalism, but about the absence of pleasant variations and of the tired look to the thing. For all the weird stuff that cropped up on my iPad2, Trello is still more attractive. &amp;nbsp;A name like Nokahuna raises expectations a little higher, and the visual appeal of a list just doesn't meet that expectation.&lt;br /&gt;&lt;br /&gt;Summary: I'm sure both work well enough on a desktop browser. Trello aims at being multi-platform, but doesn't seem to have reached that goal in practical terms. Nokahuna is the more minimal of the two, perhaps too much so; Trello is more feature filled, almost trendy. Minimalism aside, Nokahuna still needs a facelift.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3942386310914770230?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3942386310914770230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3942386310914770230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3942386310914770230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3942386310914770230'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/nokahuna-and-that-other-task-manager.html' title='Nokahuna and That Other task manager'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-241817686332603759</id><published>2011-09-21T18:51:00.000-07:00</published><updated>2011-09-21T19:01:16.841-07:00</updated><title type='text'>Conundrum, a sample of UTF-8 in Ruby 1.9.2</title><content type='html'>&lt;div&gt;Posted to Github as &lt;a href="https://gist.github.com/1233852"&gt;this gist&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# encoding: utf-8&lt;/div&gt;&lt;div&gt;# conundrum.rb&lt;/div&gt;&lt;div&gt;alias :λ :lambda&lt;/div&gt;&lt;div&gt;alias :Ω :abort&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;module Enumerable&lt;/div&gt;&lt;div&gt;  alias :⇔ :collect&lt;/div&gt;&lt;div&gt;  alias :∉ :reject&lt;/div&gt;&lt;div&gt;  alias :∈ :select&lt;/div&gt;&lt;div&gt;  alias :∫ :inject&lt;/div&gt;&lt;div&gt;  alias :∀ :all?&lt;/div&gt;&lt;div&gt;  alias :∃ :any?&lt;/div&gt;&lt;div&gt;end&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;class Array&lt;/div&gt;&lt;div&gt;  alias :× :each&lt;/div&gt;&lt;div&gt;  alias :⊠ :each_index&lt;/div&gt;&lt;div&gt;  alias :≡ :eql?&lt;/div&gt;&lt;div&gt;  alias :∋ :include?&lt;/div&gt;&lt;div&gt;  alias :∪ :| &lt;/div&gt;&lt;div&gt;  alias :∩ :&amp;amp; &lt;/div&gt;&lt;div&gt;end&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;%w(a b c).× do |letter| puts letter; end&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;%w(a b c).∪ %w(x y z) do |letter| puts letter; end&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;%w(a b c).∩ %w(c y z) do |letter| puts letter; end&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;a = λ {|s| puts s}&lt;/div&gt;&lt;div&gt;a.call('test')&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ω "It is the end"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-241817686332603759?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/241817686332603759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=241817686332603759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/241817686332603759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/241817686332603759'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/conundrum-sample-of-utf-8-in-ruby-192.html' title='Conundrum, a sample of UTF-8 in Ruby 1.9.2'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-9176731381664688957</id><published>2011-09-21T11:00:00.001-07:00</published><updated>2011-09-21T11:26:14.385-07:00</updated><title type='text'>I miss my Spaces</title><content type='html'>I'm sure the NC DOT has its reasons for designing roads that induce drivers to switch lanes constantly or be forced into turn-only lanes. But having a reason is not the same thing as making a good choice or making acceptable trade-offs. &lt;br /&gt;&lt;br /&gt;I'm sure Apple has its reasons for removing Spaces from OSX Lion and replacing it with Mission Control. But they went all NC DOT in the process, forcing desktops into a single lane. The result is a system which is more difficult to navigate and less functional than its predecessor. &lt;br /&gt;&lt;br /&gt;How can the seemingly simpler Mission Control be harder than the two-dimensional Spaces? Well, Mission Control isn't actually simpler. Like an NC DOT onion-skinned road design, the user is forced to shift their attention from getting to an objective destination, to a forced choice problem of avoiding undesired exits. &lt;br /&gt;&lt;br /&gt;Forcing choices on people in an interface is good when the options are potentially equally valued, and you need to determine a preference. Forced choice is a terrible thing when there is no need to determine the preference, or when there is no preference. &lt;br /&gt;&lt;br /&gt;Spaces could be used to eliminate the need to search, by using the brain's natural inclination to remember details based on physical location. Mission Control turns the direct access ability of Spaces into a linear scanning process. &lt;br /&gt;&lt;br /&gt;I'm sorry, Apple, but Mission Control is a big time FAIL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-9176731381664688957?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/9176731381664688957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=9176731381664688957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/9176731381664688957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/9176731381664688957'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/i-miss-my-spaces.html' title='I miss my Spaces'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8365106689191568009</id><published>2011-09-20T21:14:00.000-07:00</published><updated>2011-09-20T21:14:18.441-07:00</updated><title type='text'>Interesting Ruby Tidbits</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In Ruby,&lt;br /&gt;&lt;br /&gt;@@var class variables are shared between the class, its instances, and any extended classes; thus they act like globals within a superclass' hierarchy.&lt;br /&gt;&lt;br /&gt;do...end blocks bind at a lower precedence than { .. } blocks; thus,&lt;br /&gt;p a.map {|s| &amp;nbsp; s*2 }&lt;br /&gt;p a.map do |s| s*2 end&lt;br /&gt;&lt;br /&gt;"string" &amp;nbsp;is equivalent to %(string) and %Q(string), but the latter two allow nesting of quote characters without special escaping&lt;br /&gt;&lt;br /&gt;To get a list of user methods from a subclass, use the cls.methods method and subtract the base class method list from the class method list.&lt;br /&gt;&lt;br /&gt;If you use the default argument to Hash.new("default"), the value gets shared among all defaulted hash entries, so assignment to any of them will change all of them. Use the block form of default initialization instead: { |h,k| h[k] = "default" }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8365106689191568009?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8365106689191568009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8365106689191568009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8365106689191568009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8365106689191568009'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/interesting-ruby-tidbits.html' title='Interesting Ruby Tidbits'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5223409100684422323</id><published>2011-09-16T10:49:00.000-07:00</published><updated>2011-09-20T16:23:12.410-07:00</updated><title type='text'>To Quote or Not Two Quotes, Taht Iz Dah Qvestion</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In C, when one needed to insert a special character or ensure a regular character was interpreted as-is, one would use the backslash character (for those of you in Rio Linda, that's the '\', not the forward slash '/'), like so:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;\n&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;\"&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;\\&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In Ruby, supposedly you can do the same thing. The exception is that in Ruby, the action of the backslash is restricted within single-quoted strings. That is, &lt;br /&gt;&lt;br /&gt;&lt;code&gt;" this is a quote: \""  (length 18)&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;' this is a quote: \'"   (length 19)&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Be mindful of your escaping, you could be escaping too much, depending on the type of quotes you chose. This often caused trouble in our RSpec tests, particularly when Capybara "have_content" matchers were involved. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5223409100684422323?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5223409100684422323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5223409100684422323' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5223409100684422323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5223409100684422323'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/to-quote-or-not-two-quotes-taht-iz-dah.html' title='To Quote or Not Two Quotes, Taht Iz Dah Qvestion'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-279223927436265942</id><published>2011-09-14T08:39:00.000-07:00</published><updated>2011-09-20T18:29:54.733-07:00</updated><title type='text'>Once Bitten, Twice Shy</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;Got bitten but the Ruby Constants Are Not Constant bug again. Actually, it was in the same part of code that I'd found it before, only dealing with a portion of a hash a bit more deeply nested.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SOMEHASH = {&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp;:elem1 =&amp;gt; {&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;:props =&amp;gt; [ :a, :b, :c ]&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp;},&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp;:elem2 =&amp;gt; {  }&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;hash = SOMEHASH.clone&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&amp;nbsp; # replaces SOMEHASH[:elem1][:props]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;code&gt;hash[:elem1][:props] = hash[:elem1][:props].shuffle&amp;nbsp;&lt;/code&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I know, you Rubistas are going to say it isn't a bug; that it is just my naivete; that in Ruby, deep structures like nested arrays and hashes contain references to objects that do not change but the objects that are referenced can mutate.&lt;br /&gt;&lt;br /&gt;What is happening here is that the anonymous hash (the object pointed to by the key :elem1) is not being copied. Its reference is what is copied. So shuffling and replacing one of its members (:prop1) necessarily changes&amp;nbsp;SOMEHASH[:elem1].&lt;br /&gt;&lt;br /&gt;One approach is to freeze the hash, but you'll end up forcing your app to abort when it tries to manipulate values. In our app, we were creating copies of elements and shuffling them. The problem being that our copies weren't really full copies: they contained references to the objects still in our original "Constant" hash.&lt;br /&gt;&lt;br /&gt;And Matz might argue that it is not surprising, once you understand the details well enough. But it is still undesirable. I find many aspects of Ruby to be elegant, but not this one.&lt;br /&gt;&lt;br /&gt;A more gruesome, brute-force approach is to deep copy the hash by serializing the data to a stream, and marshaling it back into a new hash object. It is a one-liner, but that one line is doing a lot of work in order to copy an hash. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;def deep_copy(hash)&lt;br /&gt;&amp;nbsp; Marshal::load(Marshal::dump(hash))&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-279223927436265942?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/279223927436265942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=279223927436265942' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/279223927436265942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/279223927436265942'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/once-bitten-twice-shy.html' title='Once Bitten, Twice Shy'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-572810669699785081</id><published>2011-09-11T13:01:00.000-07:00</published><updated>2011-11-16T08:45:40.769-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>PHP Considered Inelegant</title><content type='html'>I'm looking at this year's &lt;a href="http://www.sparkcon.com/sparks/wheelspark/"&gt;SparkCon&lt;/a&gt; (2011) and noticed that the server had vomited on the sidebar. SparkCon's site apparently uses PHP to parse XML, and the parser threw an uncaught exception:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Warning: SimpleXMLElement::__construct() [simplexmlelement.--construct]: &lt;br /&gt;Entity: line 1: parser error : &lt;br /&gt;Start tag expected, '&amp;lt;' not found in /home/sparkcon/www/www/wp-content/plugins/gcal-sidebar/gcal-sidebar.php on line 369&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Well, I'm not picking on SparkCon - it looks like a fantastic set of events - but increasingly I'm feeling less and less tolerant of those kinds of fit-and-finish flaws showing up when I'm interacting with a Web site. &lt;br /&gt;&lt;br /&gt;Imagine what you would feel like if you were meeting a new business associate to chat at a cafe, and while you were talking they said "hold on...", unzipped, reached inside their undergarments to adjust themselves, scratched around for a while, and then tried to resume  with "ok, go ahead". &lt;br /&gt;&lt;br /&gt;We are all human, but some people are just more circumspect than others.&amp;nbsp;That's why, intuitively, PHP rubs me the wrong way: inelegance.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update: I'll give two examples. First, PHP's over-reliance on special characters and strings of special characters as operators in the syntax (from its Bourne shell -&amp;gt; ED/AWK/SED -&amp;gt; Perl heritage); and second, its concomitant reliance on gruesomely ugly&amp;nbsp;&lt;a href="http://stackoverflow.com/questions/7501265/testing-variables-in-php"&gt;idiomatic expressions&lt;/a&gt; for expressing trivial relations and operations. Neither of these PHP characteristics adds value to the solutions; both detract considerably from the readability of the code and &lt;a href="http://andyjeffries.co.uk/articles/4-reasons-why-ruby-syntax-is-better-than-phps-"&gt;add excessively to its code length&lt;/a&gt;. Since code-length is a correlate of error injection rate, PHP is objectively a worse basis for making an investment in code.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;I'm not sure if PHPs inelegance is entirely justified as a conclusion, but PHP isn't alone.&amp;nbsp;PHP lacks the charming Rube Goldberg contraptions of Ruby metaprogramming, elegant to some but &lt;a href="http://blog.deobald.ca/2011/10/clojure-macros-how-evil.html"&gt;a sham to others&lt;/a&gt;.&amp;nbsp;Perl is its ugly older brother, so ugly that it almost goes all the way around the ugly clock with one liners that appear elegant for how tightly they can compress their ugliness. And as bloated as the JVM platform has become, Java was not a particularly elegant language even when it started. JavaScript is like a fractured gem: turn it one way, and it looks elegant, turn it another and the flaws ruin the illusion. And then again, the apparent elegance of a language is not always sufficient to offset poor run-time performance. &amp;nbsp;PHP is just the scab I'm picking at today.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;See also &lt;a href="http://www.bitcetera.com/en/techblog/2009/04/07/10-reasons-why-php-is-still-better-than-ruby--/"&gt;this tongue-in-cheek comparison&lt;/a&gt;.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-572810669699785081?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/572810669699785081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=572810669699785081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/572810669699785081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/572810669699785081'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/why-i-dislike-php.html' title='PHP Considered Inelegant'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-1320954684258063777</id><published>2011-09-09T15:05:00.000-07:00</published><updated>2011-09-09T15:06:56.143-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Passion Considered Harmful</title><content type='html'>I had a discussion with a colleague recently, and she was telling me about work in the university. As we parted ways, she quipped that for those university jobs, one really "needed to be passionate about education." &lt;br /&gt;&lt;br /&gt;I'm sure that she was serious, and in some ways it is true. I'm also sure that there over 50% of the people working in those jobs who could be said to be less than passionate. Middle-manager dreary even. I've seen those people at work, and the utter banality of their expressions is sometimes just torturous to watch. So naturally I'm a little confused by the apparent contradictions. &lt;br /&gt;&lt;br /&gt;My question is, why? &lt;br /&gt;&lt;br /&gt;It is important to be committed to what you are doing. My question is why is it necessary to be so passionate that you never stop to think about whether it is important or good. We could save a lot of really worthless economic activity, not to mention heartache and grief, with a little dispassionate introspection. &lt;br /&gt;&lt;br /&gt;Should we encourage teens to join the sex industry, since many teens are passionate about sexual activity? Passion is not the source of commitment. &lt;br /&gt;&lt;br /&gt;Nor is passion a necessary outcome. I want my doctor to be keenly interested in his profession, to be dedicated and deeply involved in whatever it is that he specializes in.  But I don't want him to have an unusual excitement, enthusiasm, or compelling affinity for his mode of treatments above alternative protocols that are equally valuable. &lt;br /&gt;&lt;br /&gt;A doctor's attachment to his specialty should not cloud his judgement about your specific situation. Passion is a fog to judgement, a useful motivator but deadly without restraint. &lt;br /&gt;&lt;br /&gt;Besides which, people lie about being passionate. They especially exaggerate their passions when it is perceived to affect their job prospects. Sometimes, a pretense of passion can indeed turn into the real thing. Yet the incessant drumbeat for passion has become such a common refrain that it has corrupted and colored the very message it was meant to filter.  &lt;br /&gt;&lt;br /&gt;Professional actors are paid to present a pretense of passion. Such passion is hollow at best - a clever deception for our own amusement - but it is all too common to find people who can act a passionate role with excellence but have little value for honesty and integrity. &lt;br /&gt;&lt;br /&gt;In marriage, passion without honesty, integrity, and commitment is just a precursor to divorce, or worse. Passionate actors poison their relationships. &lt;br /&gt;&lt;br /&gt;Passion shouldn't be an acid test. It shouldn't even be the first thing you look for. Look for healthy relationships instead. When you find them, the passion will grow out naturally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-1320954684258063777?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/1320954684258063777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=1320954684258063777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1320954684258063777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1320954684258063777'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/reason-for-being.html' title='Passion Considered Harmful'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-1645282807876158847</id><published>2011-09-08T14:11:00.000-07:00</published><updated>2011-09-08T14:11:09.789-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Social Networking'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Marginalizing Your Peers</title><content type='html'>I'm reading a blog by S. Iannarino, in an entry titled &lt;a href="http://thesalesblog.com/2011/09/no-garbage-in-no-garbage-out/"&gt;"No Garbage In, No Garbage Out."&lt;/a&gt; Now, Iannarino's material is a little above the fold compared to some sales and marketing pieces, but it is still more pop psychology than rocket science.  Among the pithy aphorisms and exhortations, Iannarino repeats a few recommendations I've heard often. Just as often, they give me pause. &lt;br /&gt;&lt;br /&gt;One of his exhortations is "avoid negative people." Now, on the surface, it seems quite reasonable, even almost natural. An uplifting environment and the comfort of intelligent, positive peers is definitely better.  But it has always bothered me a little bit that what the pop-positive-psych-preachers propose to get there, is essentially that we abandon those most in need just so we can protect a personal pie-in-the-sky mental state. &lt;br /&gt;&lt;br /&gt;Think that's too extreme? Am I being too negative? &lt;br /&gt;&lt;br /&gt;What does this recommendation say about how you should widows, orphans, poor, under/unemployed, sick, those coworkers nobody really knows well, or some minority class of the disenfranchised? No, I'm not writing here of abstract groups who see themselves as victims, but those real people that you contact that actually have stresses and struggles. Their coping mechanisms don't always compensate. &lt;br /&gt;&lt;br /&gt;What this advice says, essentially, is "Let them go to Hell, so I can pretend I'm in Heaven."&lt;br /&gt;&lt;br /&gt;Selfish rule making like this is one of the reasons why a Sales and Marketing mentality is so bereft of ethical standards, and why honesty, transparency, and trust are so much harder to come by in the business world. By narrowing their own focus based upon their own personal dogma, they marginalize their neighbors. &lt;br /&gt;&lt;br /&gt;They are also probably discard the wisdom of more realistic minds. A study I read suggested that depressive tendencies in kids is usually associated with a more accurate self-assessment, than of more up-beat peers.&lt;br /&gt;&lt;br /&gt;Put another way, knowledge isn't always as uplifting as it is made out to be. The fruit of the tree of knowledge may have been a way of opening the eyes to good and evil, but it also had the effect of excluding its consumers from a garden of ignorant bliss. Ignoring people who complain may be wise; but conversely you may also be ignoring their wisdom.  &lt;br /&gt;&lt;br /&gt;There is a place for assertiveness when dealing with people who have trouble coping. But it is not assertive to avoid people just because they challenge your world view, force you to consider risks, account for costs, or consider consequences. No, that is far closer to passive-aggressive cowardice. &lt;br /&gt;&lt;br /&gt;There is no particular place in Hell reserved for those who choose to close their own ears to other's sorrows. As Jesus said in the Book of Luke (10:25-29), empathy is required for salvation. So if you're a believer who follows this sort of guidance and marginalizes people out of a sense of protecting your personal belief system, your belief isn't a free get-out-of-hell pass. Even if you're not a believer, there's no magikal taboo protection to be had in that sort of positive psychology. &lt;br /&gt;&lt;br /&gt;Don't Abandon. Learn to cope with the negativity. Help others to see past their own limitations, and mentoring those who can accept it by teaching them better coping mechanisms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-1645282807876158847?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/1645282807876158847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=1645282807876158847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1645282807876158847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1645282807876158847'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/marginalizing-your-peers.html' title='Marginalizing Your Peers'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3441085481698389333</id><published>2011-09-06T09:30:00.000-07:00</published><updated>2011-09-06T09:30:47.598-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Green Economy'/><category scheme='http://www.blogger.com/atom/ns#' term='EV'/><title type='text'>Running cars on zinc</title><content type='html'>The federal government has been pushing hydrogen research, and after looking over several research papers I'm astounded at how complicated approaches seem to take all the attention. It is as if people are more interested in playing with science than with solving practical problems.&lt;br /&gt;&lt;br /&gt;One concept that caught my eye was an Israeli solar project, which proposed a zinc/zinc oxide/water/hydrogen cycle. Even there, extreme heat is used in the process of reducing water to hydrogen. Six hundred degrees may me manageable, but it isn't really necessary.&lt;br /&gt;&lt;br /&gt;But is the zinc process practical? Well, a gallon of gas is equivalent to about 1kg of hydrogen. Hydrogen weighs about 1.01g per mole, so it would take about 990 moles of H to get the power of a gallon of gas. You need one mole of zinc to release two moles of hydrogen from a mole of water, or 495 moles. &lt;br /&gt;&lt;br /&gt;Since zinc weighs in at 65g per mole, you'd need 32178g of zinc to liberate enough hydrogen to equal a gallon of gasoline. So now we are talking about 70 lb of zinc in a powdered or slurry form. That's not counting the weight of the water you'd have to consume. The weight of 495 moles of water is about 8910g or 20 lb.&lt;br /&gt;&lt;br /&gt;It would take 10 gallons to provide for a typical commuter vehicle. Carrying around a 900 lb tank of zinc and water doesn't seem at all a good trade off to a 10 gallon gas tank. Gasoline itself weighs in at about 90 pounds. &lt;br /&gt;&lt;br /&gt;We could do the same sorts of computations to find that aluminum or magnesium would cut the weight by somewhere around 2/3rds, or around 300 pounds, which is certainly more competitive, although either metal would require more energy to reclaim.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3441085481698389333?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3441085481698389333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3441085481698389333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3441085481698389333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3441085481698389333'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/running-cars-on-zinc.html' title='Running cars on zinc'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3067070755214222148</id><published>2011-09-02T14:59:00.000-07:00</published><updated>2012-01-16T12:14:21.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><title type='text'>Git's Poor Command Line Habits</title><content type='html'>&lt;div&gt;Tom Lord's Arch, or 'tla', was one of the first open source distributed version control systems.  It was widely criticized as having overly long names and convoluted command line interface. Linus's Git has shorter names, but the command lines can be just as perverse. &lt;br /&gt;&lt;br /&gt;Take, for instance, the command to set the repository back in time by one commit:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git reset --hard HEAD^&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;OK, what's up with that?  It was not necessary at all to introduce a idiosyncratic tree walking syntax just for Git ?&lt;br /&gt;Seriously?? &lt;br /&gt;&lt;br /&gt;[edit: not to mention, git reset is as dangerous a command as rm * for pretty much the same reason.]&lt;br /&gt;&lt;br /&gt;In Git, the HEAD^ shows the parent of the HEAD commit. But wait, there's more!&lt;br /&gt;Use HEAD^^ to see the parent of the parent of the HEAD commit, if it exists, or HEAD~3 (that's a tilde, '~', not a hyphen) to show the great-grandparent. &lt;br /&gt;&lt;br /&gt;There's not a lot of consistency to the various command line interfaces in Git; most of the commands make use of a mix of positional arguments and labelled parameters and options, which can make the commands rather arbitrary and thus needlessly more difficult to remember.  The choice of command names is also rather spurious. &lt;br /&gt;&lt;br /&gt;Git has some good qualities, and lots of documentation. But lots of programmers keep complaining that they can't remember what that particular command was they were looking for, and it is evident that with Git it is difficult to infer for many of us to infer the proper semantics based on the syntax of the options.  It's not us, its you, Git! You're hard to remember!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3067070755214222148?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3067070755214222148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3067070755214222148' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3067070755214222148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3067070755214222148'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/09/gits-poor-command-line-habits.html' title='Git&apos;s Poor Command Line Habits'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4248548748402604845</id><published>2011-08-31T19:18:00.000-07:00</published><updated>2011-09-27T13:06:49.545-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><category scheme='http://www.blogger.com/atom/ns#' term='Process'/><title type='text'>Configuring a GIT controlled Web site</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;This is assuming you're using a *nix setup for the server, and Mac OSX for the workstation.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, register your public key with the server's SSH. On a shared host, this would typically be under a control panel icon for Shell Access  or SFTP/SSH .  Consult your hosting service for details. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suppose your site is "loli.pops.com" and your user name is "jonathan".&lt;/div&gt;&lt;div&gt;You should be able to log in to your site. Open a command terminal window, and:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ssh jonathan@loli.pops.com&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you can't do that and get a shell prompt, you're hosed. There are ways around it, but that's another post. Knowing how to navigate this level of complexity is a sort of prerequisite... you don't need to know, just know how to find out how to do this kind of stuff.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, you are logged in to your server, and you create a subdirectory for your repositories, and a directory for your web site or app:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mkdir -p ~/repositories/loli.pops.com.git&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You initialize that directory as a "bare" git repo. (A bare git repo has no modifiable source files present, just the repository metadata and data files). This will be the repo you will stage changes to immediately prior to deploying:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd ~/repositories/loli.pops.com.git&lt;br /&gt;git init --bare&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, you switch to another terminal, either another window or a tab. Create and/or change your to the working directory for your lili.pops site:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mkdir -p ~/workspace/loli.pops.com&lt;br /&gt;cd ~/workspace/loli.pops.com&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now, at this point, we're assuming that there are oodles and oodles of cool source files with names like "index.html" and "flavor_picker.js" just sitting around in ~/workspace/loli.pops.com.&lt;br /&gt;&lt;br /&gt;We can (we should, nay, we must!) turn the directory into a git repo (a non-bare repo with source files, that is):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git init&lt;br /&gt;git add .&lt;br /&gt;git commit -m "initial commit of loli.pops.com content"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This is the really weird part:Git links up repositories very loosely.  Git keeps data about the sets of files that are changed, which it calls a "commit". These commits can be pushed by you to bare repositories, or pulled by people working with you into their own repositories.&lt;br /&gt;&lt;br /&gt;So people contribute independently. Note also, that it isn't necessary for everyone to have complete and utter exposure to all of your files.&lt;br /&gt;&lt;br /&gt;Let's link our repository to the bare repository on the server:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git remote add staging ssh://jonathan@loli.pop.com/homes/jonathan/repositories/loli.pop.com.git&lt;br /&gt;&lt;br /&gt;# (Uhhhh.... long line folding is making this look wrong. It should all be one line.)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;What we are doing here is simply making an association between a local label "staging", and a url that points to the server's repository. In this case, we're using the SSH protocol to make the link. Since we provided a public key, we aren't going to be asked for a password in the next step.&lt;br /&gt;&lt;br /&gt;The next step is to set up a branch on the remote that will track our local main line branch, and copy our changes to it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git push staging +master:refs/heads/master&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The "+master:" part means "create a master branch on the remote repository".&lt;br /&gt;The "refs/heads/master" part means "compare the remote branch's references to references from the local head master branch".&lt;br /&gt;&lt;br /&gt;Once that association has been made between the local and remote repositories, the command to push our changes is much simpler: we just refer to the label we used ("staging"): &lt;br /&gt;&lt;code&gt;&lt;br /&gt;git push staging&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Go ahead, repeat that command. You should see:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Everything up-to-date&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;At this point, all we've done is pushed changes to a remote repository. No one can see our files because that remote is "bare" -- there is no working source tree. The most obvious way to deal with this is to go to the server and ask git to pull out a copy of the working files into some web root location.&lt;br /&gt;&lt;br /&gt;Switch back to your SSH command window, and checkout the changes on the server:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;GIT_DIR=~/repositories/loli.pop.com.git GIT_WORK_TREE=~/public_html/staging/latest git checkout -f&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here, I'm assuming that you use public_html/staging/latest as a location to push your changes to before they've been finally released.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, that's all that is necessary, but we can streamline the process by automating that last step. There are two ways to do this. One is by way of a shell script, which I'll call "deploy":&lt;br /&gt;&lt;br /&gt;&lt;code&gt;deploy.sh:&lt;br /&gt;user = ${1%%@*}&lt;br /&gt;server = ${1##*@}&lt;br /&gt;branch = $2&lt;br /&gt;git push $server $branch&lt;br /&gt;ssh ${user}@$server "GIT_DIR=~/repositories/loli.pop.com.git GIT_WORK_TREE=~/public_html/staging/latest git checkout -f"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Well, that's a rough guesscript. It looks like it would work, but I haven't tested it.&lt;br /&gt;&lt;br /&gt;Another way is by a Git "hook". Go to the SSH window, and run the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd ~/repositories/loli.pop.com.git&lt;br /&gt;cat &amp;gt;&lt;eot&gt; "hooks/post-update" &amp;lt;&amp;lt;EOT&lt;br /&gt;GIT_DIR=~/repositories/loli.pop.com.git GIT_WORK_TREE=~/public_html/staging/latest git checkout -f&lt;br /&gt;EOT&lt;br /&gt;chmod u+x "hooks/post-update"&lt;br /&gt;&lt;/eot&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now, whenever you do a git push staging, the post-update hook on the server will do the checkout for you.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Note: if you are deploying applications, you probably already use a .htaccess file or alternatives to hide or block access to resources that aught not to be exposed on your site. &lt;/em&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4248548748402604845?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4248548748402604845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4248548748402604845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4248548748402604845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4248548748402604845'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/configuring-git-controlled-web-site.html' title='Configuring a GIT controlled Web site'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3821535063792793182</id><published>2011-08-21T19:53:00.000-07:00</published><updated>2011-08-21T19:53:49.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Design'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='Content Management'/><title type='text'>A case for web site Minimalism</title><content type='html'>It has been several months since my old Joomla based site was hacked. At the time the workaround was to put up a static placeholder page, with minimal contact information on it. It seems as if the time has come to revisit the site, now that I'm again on the prowl for more work. &lt;br /&gt;&lt;br /&gt;While I endeavor not to lose focus, too many questions arise. "Why?" for instance. My Web site has &lt;i&gt;never&lt;/i&gt; been a source of clients. For technical communication purposes I blog here, and for project work I use external services like github. There is just a little bit of lie to the oft told tale that a business "needs a Website". &lt;br /&gt;&lt;br /&gt;What a business needs is a reputation. A Website is just one location people expect to help them inform their own opinions. Most people don't bother to read, let alone dig around for  information, so unless a bit provides some meaningful novelty that contributes to your reputation that bit should be discarded. &lt;br /&gt;&lt;br /&gt;And that's just information on a static site. Bits in database driven CMS sites come with much higher initial costs, a greater ongoing maintenance burden, and unmeasured risk exposures. Is a PHP content management system a worthwhile expense? Maybe. Is it an investment in an asset? It could be, if your brand is worth something. But from a technology perspective most CMS systems present more of a liability than asset.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3821535063792793182?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3821535063792793182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3821535063792793182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3821535063792793182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3821535063792793182'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/case-for-web-site-minimalism.html' title='A case for web site Minimalism'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4387879478663525926</id><published>2011-08-18T19:10:00.000-07:00</published><updated>2011-08-18T19:10:21.497-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Debugging Consoles with Ruby</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In ruby the debugger is not nearly as nifty as the console. Fortunately, there is&amp;nbsp;&lt;a href="https://github.com/pry/pry"&gt;https://github.com/pry/pry&lt;/a&gt;, a gem that provides an embeddable console. &amp;nbsp;In the simplest terms, Pry provides real-time access to your program's state through a&amp;nbsp;Read-Eval-Print-Loop, much like Rails' console.&lt;br /&gt;&lt;br /&gt;I've been a shell programmer for most of my working life, but I've never, ever, ever, been a fan of REPL user interfaces. They suck. &amp;nbsp;Readline interfaces are fine for shell tools, but there's no particular reason the user interface has to be line-oriented.&lt;br /&gt;&lt;br /&gt;One of my first computers, an Atari 130XE, had an interesting editing interface for prototyping code. &amp;nbsp;It kept lines in a buffer, and supported both immediate execution (of un-numberd lines) and editing (of numbered lines). &amp;nbsp;Buffering, baby, buffering! &amp;nbsp;That's the difference between a 30 year old 8k BASIC console and a modern Ruby console: in-place editing.&lt;br /&gt;&lt;br /&gt;But wait -- we can get a first approximation of in-place editing by cleverly hooking in an editor component. A quick search turned up two possibilities: &amp;nbsp;&lt;a href="http://sketches.rubyforge.org/"&gt;http://sketches.rubyforge.org/&lt;/a&gt; &amp;nbsp;and &amp;nbsp;&lt;a href="https://github.com/jberkel/interactive_editor"&gt;https://github.com/jberkel/interactive_editor&lt;/a&gt; . I gave the interactive_editor gem a try.&lt;br /&gt;&lt;br /&gt;To summarize, in a Rails 3.x app, you would just add the two gems to your Gemfile, run bundle, and then embed the expression&lt;br /&gt;&lt;br /&gt;&lt;code&gt;binding.pry&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;in your code where you want the console to open.&lt;br /&gt;&lt;br /&gt;There are a few other details. The &lt;a href="http://media.vimcasts.org/videos/20/irb_and_vim.m4v"&gt;vimcast&lt;/a&gt; has some useful tips on setting up the interactive_editor, for instance, to make sure you get nice colorization turned on. But after that, using it is a breeze. Just use&lt;br /&gt;&lt;br /&gt;&lt;code&gt;vi&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;to open a vim editor into a temporary buffer. When you save and close, the console will run your code. Running vi again will reopen the last temporary file. It's a VEPL, &amp;nbsp;a Vim-Eval-Print-Loop.&lt;br /&gt;&lt;br /&gt;But even more interesting for debugging, you can use the editor to work with objects through YAML representations. &amp;nbsp;Just add ".vi" to the end of an object, and your vim editor will open with the YAML. For instance, in UserController#update, I might do:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;@user.vi&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You get something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;nbsp; 1 --- !ruby/object:User &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; 2 attributes:&lt;br /&gt;&amp;nbsp; 3 &amp;nbsp; id: 2&lt;br /&gt;&amp;nbsp; 4 &amp;nbsp; email: mitch.amiano@agilemarkup.com&lt;br /&gt;&amp;nbsp; 5 &amp;nbsp; encrypted_password: $2a$10$s/NKiMEC1UfHzgG5JlCCJuHpZbAZ77dz623rq6gt12YUqW7RpvoWW&lt;br /&gt;&amp;nbsp; 6 &amp;nbsp; reset_password_token:&lt;br /&gt;&amp;nbsp; 7 &amp;nbsp; remember_token:&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;and so on (except, nicely colorized if you followed the vimcast).&amp;nbsp;&lt;/div&gt;&lt;br /&gt;Not only is it much easier to look at and inspect than a puts or the debugger's "p" output, but the YAML is a mutable representation. Editing it, saving and closing will modify the in-memory object. You could do this sort of hot debugging already, but the editor makes it a lot easier to visualize, and lets you tweak multiple properties in one step without having to type any code. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4387879478663525926?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4387879478663525926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4387879478663525926' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4387879478663525926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4387879478663525926'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/debugging-consoles-with-ruby.html' title='Debugging Consoles with Ruby'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3701611576203403901</id><published>2011-08-16T21:51:00.000-07:00</published><updated>2011-08-17T06:39:34.805-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><category scheme='http://www.blogger.com/atom/ns#' term='Process'/><title type='text'>Is DRY a little wet? Part 2</title><content type='html'>A more fundamental fallacy behind DRY is the illusion of orthogonality. That is, hierarchical categorization is by and large achieved through a self-imposed discipline. Even where structural relationships are apparently observable in physical, neither the naming or the affiliations of parts are essential, intrinsic properties of the system.&lt;br /&gt;&lt;br /&gt;Like Feynman's birds, one can know all the names for a creature in every human language, and yet know nothing at all about the animal itself.&lt;br /&gt;&lt;br /&gt;I know, I know, it is a fine distinction, possible to the point of splitting hairs. Software systems are systems of logic, and as such they are synthetic human contrivances, are they not? So why can't we just assert that one perspective take precedence, and rationalize that the collection of all properties forms a space with an orthogonal basis?&lt;br /&gt;&lt;br /&gt;Well, we can deliberately live in such denial. That's just the kind of linear thinking that has served the scientific and engineering communities well over the past few centuries. It is quite pragmatic in fact. &lt;br /&gt;&lt;br /&gt;Yet it is also self-limiting. Eventually, the addition of features causes the system to undergo a phase change, as thresholds are reached in the expressiveness of the supposed authoritative source, and the constructions of the relations from the source to the dependent sinks. &lt;br /&gt;&lt;br /&gt;More pragmatically, the fallacy can take root in the form of overt and aggressive over-simplification, in which the developer mistakes a source for a sink, and summarily discards it.&lt;br /&gt;&lt;br /&gt;Algebra is the branch of mathematics that speaks to orthogonality, giving us the axioms and theorems by which to formally comprehend how such systems are structured. If we look at a software system as if it were some abstract vector space, this would tell us that there must exist some set of primitive vectors that form a basis for the space. Such a basis need not be finite, but ideally it is free of interdependencies... any one given basis vector cannot be generated by any combination of the remaining basis vectors. Approaching that kind of behavior is an objective of DRY. Improperly identifying the supposed basis, the "single source of information," is the underlying cause of the fallacy described here.&lt;br /&gt;&lt;br /&gt;What Algebra cannot tell us, is how will one representation of information varies with respect to another, between stakeholders or over time. It is dead on exact regarding the dependent representations, but an Algebraic system cannot determine its own axioms. The real world is the primary source. In practical terms, this is why normalization, founded though it is on mathematical theory, is yet still a very subjective practice. &lt;br /&gt;&lt;br /&gt;DRY must be just as subjective, if not more so, for it is a(n informal) form of normalization. Coincidence in space does not imply connection, and precedence in time does not imply causality, yet it seems to be common practice for some programmers to rely heavily upon such contingent phenomena to "DRY up" their code.&lt;br /&gt;&lt;br /&gt;Programmers may even assert that as professionals, they know better than the customer, swapping out explicit distinctive representations in exchange for implicit dependencies upon co-incident data. Doing so may be a useful contingency while prototyping, but it is still a rationalization based upon assumptions. Not acknowledging that it compromises the model, if just a little bit at a time, is personal myopia but more critically this mode of thinking encourages retroactive imbedding of structural flaws. &lt;br /&gt;&lt;br /&gt;Dealing with customers over how software should behave is a very probabilistic endeavor, and a world governed by rapidly changing probabilistic entities will only exhibit linear structure as an average over all the events and elements in its history. This indicates that doing "just enough" with respect to comprehending the source representation's dimensions will be a persistent cause of of rework, and a major injector of latent flaws. Yet we don't want Big Design Up Front- the shifting of the problem space makes that an even bigger risk factor. What to do?&lt;br /&gt;&lt;br /&gt;I would suggest adopting confrontational forced choice testing whenever a supposed functional dependency is about to be removed and a source eliminated, and it seems the least bit questionable. In an optical exam, a confrontation test forces each eye to inspect a target independently, and a forced choice test is given when corrective lenses are progressively passed through, and beyond, optimal ranges. The idea is to force the subject just a little beyond their capabilities, to better assess the best overall focal corrections to make along multiple dimensions. The candidate bit - the "information source" for removal - is potentially a critical dimension of the problem; what is the strength of the concept in the customer's language? Even if it doesn't have a name, how established is it in the domain? Things the programmer thinks he sees may be his own figments and should be subjected to increased scrutiny as information sources. Ask what would happen if some other information sources were not present or altered after factoring out the candidate bit - if the other source has any impact at all on any one of the dependencies of the candidate it should determine them all, and only together.  Functional dependencies cannot be partial. Ask yourself, after removing a candidate bit, have you introduced multiple conditionals where previously there was one or none? The more conditionals introduced, the further the system has become from being based on well-factored information sources.&lt;br /&gt;&lt;br /&gt;In general, I lean toward explicit representations of feature information. Code should say what it means, and mean what it says, within the constraints of the expressiveness of the technology. DRY is not a reasonable justification for relying upon coincidence in your code, it is telling us not to multiply factual data or relations unnecessarily in our constructions. We used to call that Occam's Razor. &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3701611576203403901?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3701611576203403901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3701611576203403901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3701611576203403901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3701611576203403901'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/is-dry-little-wet-part-2.html' title='Is DRY a little wet? Part 2'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-500154462210477371</id><published>2011-08-16T20:52:00.000-07:00</published><updated>2011-08-16T20:52:02.640-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Is DRY a little wet? Part 1</title><content type='html'>DRY is a principle articulated by Agile practitioners (IIRC pragmatic programmers Dave Thomas and Andy Hunt are credited with coining and popularizing the term), which is supposedly often misapplied. Don't Repeat Yourself is the acronym, and the principle is stated as: &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.&lt;/blockquote&gt;&lt;br /&gt;The supposed fallacy that gives rise to the misapplication of DRY is being too narrowly focused upon one particular aspect of the system, commonly a project's source code base. Single-sourcing is the objective, not code reduction.&lt;br /&gt;&lt;br /&gt;Now, kudos to the pragmatic programmers, but even more to all those technical writers who worked on single sourcing production processes, and the set-theoreticians who gave us relational normal form practices. If these other practitioners explored single sourcing and orthogonality for decades prior, the development community should be wary about just why it is they themselves as a profession are so late to the game, and what plays they might have missed along the way. &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-500154462210477371?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/500154462210477371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=500154462210477371' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/500154462210477371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/500154462210477371'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/is-dry-little-wet-part-1.html' title='Is DRY a little wet? Part 1'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-870679584437896287</id><published>2011-08-12T16:54:00.000-07:00</published><updated>2011-08-12T18:40:05.462-07:00</updated><title type='text'>When acting "Professional" is anything but</title><content type='html'>There is an interesting antipattern of communication exhibited by many diverse professionals, when dealing with clients, namely, of asserting a direction that one should take even when it works across the purposes or completely against the client's apparent interests. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two cases come to mind. There is the consulting software developer who does just enough to get by while carefully eliding any discussion of alternatives, consequences, or expectations of future outlays. The programmer exercises creative license when he chooses to build out crude approximations rather than represent the most likely costs and risks of minimally viable features; he walks the line when he continues to avoid generalizing solutions no matter what life cycle stage the system is at; but he crosses over when the customer asks for and expects a certain level of architectural repeatability and well-factored, reusable patterns, but gets point-to-point wired-up, one-off code instead.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is also the all-knowing expert doctor. Recently, an eye doctor gave a prescription for glasses. I explained to him my difficulties in dealing with a previous doctor -- of being given false diagnoses, and the doctor's refusal to discuss options.  Naturally, as an expert, the doctor nodded his head and did an exam, explaining to me the condition of my eyes and recommending progressive lenses.  Well, the progressives were weird and unfortunately the optical shop could not get the prescription right. Everything looked trapezoidal with them, and half my peripheral world was always fuzzy. I never purchased the glasses.  "That's stupid," I thought, "why would anyone want to live life with such an irritating gimmick making their eyes go buggy?" Explaining this to the doctor, I asked for contact lenses. By now he has put me in a pigeon hole, and instead of giving me a prescription that works, he gives me one fuzzy left contact and one overcorrected right contact. And I can't see anything as clearly as with my old glasses. "Give it two weeks," he says, "I've been doing this for 25 years". Well, I've had my eyes for over 47 years, and I know what I wanted, and it wasn't monocular vision with my eyes going all googley and being out of focus for two weeks. The contacts lasted for two hours before they got shelved. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In general, consultants are trained to think assertively, and the more successful consultants learn to steer clients in directions favorable to their pocketbook. Yet it is easy for that assertiveness and persuasiveness to push one down a slope of ethical blindness. The practice speaks to a lack of trust in the client's ability to look after their own interest, a parasitic paternalism emerging spontaneously from the professional relationship. At best, it leads to willful ignorance of the client's intentions. At worst, the process can bilk the client out of countless hours and lead down a path too costly to maintain. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-870679584437896287?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/870679584437896287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=870679584437896287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/870679584437896287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/870679584437896287'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/08/when-acting-professional-is-anything.html' title='When acting &quot;Professional&quot; is anything but'/><author><name>Mitch Amiano</name><uri>https://profiles.google.com/103438136844746344197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-gDTKn9hWuz8/AAAAAAAAAAI/AAAAAAAAABc/ZNrdgOVU31c/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3805791696083328183</id><published>2011-07-23T17:16:00.000-07:00</published><updated>2011-07-23T17:16:36.080-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UNIX'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='Graceful Degradation'/><title type='text'>Apple HFS as a provencial technology</title><content type='html'>Mac's HFS+ filesystem is case insensitive. I'm a little disappointed that Apple is so provincial and short-sighted.&lt;br /&gt; &lt;br /&gt;$ touch "Amy"&lt;br /&gt;$ touch "aMy"&lt;br /&gt;$ touch "amY"&lt;br /&gt;$ ls&lt;br /&gt;Amy&lt;br /&gt;^ only one file got created&lt;br /&gt;but&lt;br /&gt;$ touch eñya&lt;br /&gt;$ touch enya&lt;br /&gt;$ ls&lt;br /&gt;eñya&lt;br /&gt;enya&lt;br /&gt; &lt;br /&gt;So it is OK for some characters to automagically translate but it is not OK for others.&lt;br /&gt; &lt;br /&gt;Be very careful when copying files from the Web to a Mac. One supports international alphabets in file names, the other apparently does not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3805791696083328183?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3805791696083328183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3805791696083328183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3805791696083328183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3805791696083328183'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/07/apple-hfs-as-provencial-technology.html' title='Apple HFS as a provencial technology'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7075303170575822478</id><published>2011-07-23T17:13:00.000-07:00</published><updated>2011-07-23T17:13:05.285-07:00</updated><title type='text'>Pairing for the Imperfect</title><content type='html'>Consider System. Faults. Expected Behavior. &lt;br /&gt;Reconsider. How to go from Here to There?&lt;br /&gt;How to make it work. &lt;br /&gt;Maximize coherence, minimize arbitrary decision points.  &lt;br /&gt;Now, go. &lt;br /&gt; &lt;br /&gt;Have "pair" step in after work is halfway there. &lt;br /&gt;Explain. Rationale rebuffed.&lt;br /&gt;"Need to make it go," is the reason, "need to rethink" is the justification. &lt;br /&gt;Toss out the changes. Then watch as he goes about.&lt;br /&gt; &lt;br /&gt;Considering System. Ignore faults as unimportant. Dismiss Expected Behavior.&lt;br /&gt;Substitute bald assertion for consideration. Just enough to get by for now. &lt;br /&gt;Ignore coherence, let number of arbitrary decision points float freely. &lt;br /&gt;Spend more time fixing faults instead of providing functionality.&lt;br /&gt;Repeat.&lt;br /&gt; &lt;br /&gt;I've seen that process play out over and over now. Enough to realize that it is a well-defined strategy for playing out a work slowdown while simultaneously playing up to the customer's desire for immediate satisfaction.  &lt;br /&gt; &lt;br /&gt;Often, after repeating the latter loop two or three times, it dawns that the first path was the right way to go.  Except that in a dishonest environment the original authorship will be discarded, the ideas having been surreptitiously adopted by those who were initially dismissive.  This is an antipattern that pervades the tech industry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7075303170575822478?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7075303170575822478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7075303170575822478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7075303170575822478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7075303170575822478'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/07/pairing-for-imperfect.html' title='Pairing for the Imperfect'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3171559205242020352</id><published>2011-07-04T21:25:00.000-07:00</published><updated>2011-07-04T21:25:03.631-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><title type='text'>Spurious environments give spurious results</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I've said before, and will say it again: the suitability of a programming environment (or platform, or language, or technology stack) to a task is inversely proportional to the number of coercive statements you have to use it to get it to behave the way that is intended.&lt;br /&gt;&lt;br /&gt;Put another way, if you find yourself trying to trick your computer to get it to do what you want it to do, you probably aren't working with the right mix of technologies. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;That said, most programmers must give in to that dark impulse on a daily basis, creating elaborate fictions as it were, because the mix of technologies they must tolerate is often very unsuitable. Sometimes it seems as if the entire profession is working at the level of medieval barbers, just hacking at bits and hoping their patients don't die before paying the bills.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A similar heuristic is that an operating environment will be as predictable (unpredictable) as it is closed (open). Or, stable environments give stable results, and spurious environments give spurious results. &amp;nbsp;You're likely to see this in Web programming when developers fail to grasp the idea of closure, and do not ensure that deployments are provisioned in precisely the same way as development and test environments.&lt;br /&gt;&lt;br /&gt;For instance, the difference in a database from version 5.93 to 5.94 is not likely to be very great, but most of the likelyhood of failure arises from the fact that there is a difference, not the particular version numbers used.&lt;br /&gt;&lt;br /&gt;I keep running into this issue with a Rails project, because "rake," one of the most central tools in the tool chain, is being treated as a shared component. Rake gets updated from 0.8.7 to version 0.9.2 by the bundler at some point, and things start to break. &amp;nbsp;Fortunately, bundler complains:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;You have already activated rake 0.9.2, but your Gemfile requires rake 0.8.7. Consider using bundle exec.&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The "bundle exec" thing is a little misleading perhaps, but at least it is actually telling the truth. The punt for now is to gem uninstall rake and remove the 0.9.2 version. The honest solution is to make sure each project gets to see only its own version of rake.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3171559205242020352?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3171559205242020352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3171559205242020352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3171559205242020352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3171559205242020352'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/07/spurious-environments-give-spurious.html' title='Spurious environments give spurious results'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2575121122039640299</id><published>2011-06-14T04:47:00.000-07:00</published><updated>2011-06-14T04:47:58.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>The road less travelled</title><content type='html'>I've noticed a pattern. Whether in my coding or homework when I was in school, it felt as if life was playing tricks on me. &lt;br /&gt;&lt;br /&gt;Life is full of ambiguities. People use language in ways that leave open all kinds of possibilities, and yet they consider themselves to be honest and forthright. More subtly, they assume that others have perfect knowledge, or unwaivering attention.&lt;br /&gt;&lt;br /&gt;And I find that I notice things that others do not. Unfortunately the things I notice are often not central to reaching my goals and objectives. Hyperawareness goes hand in hand with attention deficits. I've been called perceptive, but what it comes down to is that noisy environments are very disruptive to my thinking. Then again, silent and still environments are very sterile and quickly lead to feelings of isolation. &lt;br /&gt;&lt;br /&gt;While my attention holds together, I do not seem to decode messages in the same way others do. I have been acused of deliberately misconstruing others' views; one English teacher thought my opinions in a book report was a willful misreading of the text, going so far as to insult me in his feedback comments. It seems as if, when there are multiple possible interpretations (and even when there are not), my brain chooses the one which is least obvious. &lt;br /&gt;&lt;br /&gt;Expressing opinion becomes an impractical proposition when your thinking is always orthogonal to that of the people around you. It can seem as if your thinking is always cutting against the grain. It means that the group dynamic works against you, countering your every thought, leaving you feeling drained instead of enlightened.&lt;br /&gt;&lt;br /&gt;Seeking out the less traveled road wouldn't be so bad if it were a practical problem solving strategy at an individual level. Mostly, it is not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2575121122039640299?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2575121122039640299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2575121122039640299' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2575121122039640299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2575121122039640299'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/06/road-less-travelled.html' title='The road less travelled'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5053410614256228550</id><published>2011-06-13T18:55:00.000-07:00</published><updated>2011-06-14T03:57:37.097-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><title type='text'>Another fine mess</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;One of the hardest things about programming is when your eyes betray you. A simple twiddled character becomes an extended debugging session, or hours of meaningless research.&lt;br /&gt;&lt;br /&gt;That happened today. I was installing Postgres with Homebrew on my Mac OSX, for a Rails application originally on MySQL. Well, I was getting this:&lt;br /&gt;&lt;br /&gt;rake db:migrate&lt;br /&gt;rake aborted!&lt;br /&gt;Please install the postrgesql adapter: `gem install activerecord-postrgesql-adapter` (no such file to load -- active_record/connection_adapters/postrgesql_adapter)&lt;br /&gt;&lt;br /&gt;Tasks: TOP =&amp;gt; db:migrate =&amp;gt; environment&lt;br /&gt;(See full trace by running task with --trace)&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you check Google you see scores of helpful suggestions &lt;a href="http://stackoverflow.com/questions/3347537/please-install-the-postgresql-adapter-gem-install-activerecord-postgresql-adapt"&gt;like these&lt;/a&gt;&amp;nbsp;, suggesting that it is a mismatch between the memory model used to build the pg gem, and that used to build the Postgres library.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What can also happen is that you write something like this in your database.yml:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;development:&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;adapter: postrgesql&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Egads! Look at the latest changed code first. Then have someone else look at your code. If you don't have a co-operative coworker to lend you a spare set of eyeballs, do a diff on another working file (that's how I ended up finding it). Otherwise all that internet advice is just so much more misdirection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There was also some other spurious warnings about Rakefile and DSL. &amp;nbsp;It turned out to be a feignt, a minor diversion, quickly &lt;a href="http://stackoverflow.com/questions/6199301/global-access-to-rake-dsl-methods-is-deprecated"&gt;cleared up by Stack Overflow&lt;/a&gt;. So, yep, maybe Googling is a useful technique, but don't rely on it too much. It cannot make up for a lack of&amp;nbsp;eye-worthiness.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5053410614256228550?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5053410614256228550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5053410614256228550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5053410614256228550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5053410614256228550'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/06/another-fine-mess.html' title='Another fine mess'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-593674570710381007</id><published>2011-05-18T07:05:00.000-07:00</published><updated>2011-05-18T07:05:20.572-07:00</updated><title type='text'>Problems with Pictures</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;A client recently sent a use-case document as a requirements specification, and after quite a bit of discussion the team decided that, while it might have been good as an exercise for the client, the result was still a bit far off -- and missed the point that what the project needs is more dialog. &lt;br /&gt;&lt;br /&gt;Well, there are lots of other issues there, but I went looking for use-case examples. Alistair Cockburn is a prolific writer on the subject, and his stuff makes sense in so far as one is following a use-case driven approach.&lt;br /&gt;&lt;br /&gt;I was struck by the disconnect between the pictographic use-case techniques and the use-case narrative templates. &amp;nbsp;Pictures can say a thousand words, it is true, but strangely enough it can actually be very difficult to vocalize what is presented in use-case pictograms. &amp;nbsp;It not only requires translation, but you have to be a bit of an archeologist and forensic linguist as well, to come up with wording that accurately maps what is in the pictogram. And even then, you probably missed some obscure but important details. &lt;br /&gt;&lt;br /&gt;Pictures are great for conveying emotion, giving a fuzzy sense of the breadth and connectedness of parts of the problem, and the intended strategies of a solution. But if they make the reader do extra work or suggest detail that isn't there, that is a bad thing.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-593674570710381007?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/593674570710381007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=593674570710381007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/593674570710381007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/593674570710381007'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/05/problems-with-pictures.html' title='Problems with Pictures'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7817074571906321960</id><published>2011-05-17T07:12:00.000-07:00</published><updated>2011-05-17T19:13:39.611-07:00</updated><title type='text'>Par Fried Programming</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;This is a kind of code smell, or more precisely a &lt;i&gt;coding&lt;/i&gt;&amp;nbsp;smell.&lt;br /&gt;&lt;br /&gt;Par frying is a technique used in cooking french fried potatoes, the goals being to increase the fat content and crispyness of the product. &amp;nbsp;In the context of the fast food industry partial cooking is useful because it&amp;nbsp;reduces the time needed to prepare the product for sale at the retail end-point.&lt;br /&gt;&lt;br /&gt;In the context of programming, a par frying is what happens when the coding for a given feature is left with small parts worked on but in an inconsistent and incomplete state, during a given coding session. I find that some technology stacks tend to encourage parcoding more than others.&lt;br /&gt;&lt;br /&gt;I would guess that parcoding increases jointly proportional to the dispersion of responsibilities around the stack and the time spent performing tasks not directly implementing the application feature&amp;nbsp;(such as debugging interfaces; working around flaws in the technology stack; testing routine features of the stack; and writing internal documentation).&lt;br /&gt;&lt;br /&gt;Parcoding can also increase when you are tired, sick, or otherwise stressed.&lt;br /&gt;&lt;br /&gt;Some degree of parcoding is normal... it is the vision we keep in our working memory that allows us to bridge the gap and finish with something that is more than half-baked. But technology stacks and applications are so poorly organized that they tend to overextend the working memory, giving rise to parcoding behavior patterns that will feed back on themselves. &lt;br /&gt;&lt;br /&gt;There are greater factors responsible for turning your projects into &lt;a href="http://www.amazon.com/Death-March-2nd-Edward-Yourdon/dp/013143635X"&gt;Yourdon's Death March&lt;/a&gt;es, but leaving things incomplete should only be done if you intend to abandon the code. When you par code, that's basically what you're doing: abandoning a half-baked train of thought. &amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7817074571906321960?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7817074571906321960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7817074571906321960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7817074571906321960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7817074571906321960'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/05/par-fried-programming.html' title='Par Fried Programming'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3452814987779785316</id><published>2011-05-16T08:05:00.000-07:00</published><updated>2011-05-16T08:05:10.314-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Universal Design'/><title type='text'></title><content type='html'>Ahhhhhhhhhhh! I just tried to use the VoiceOver accessibility feature of the iPad 2 on an ms word attachment. &lt;br /&gt;&lt;br /&gt;Painful at best. &lt;br /&gt;&lt;br /&gt;The top and bottom of pages are unreachable. &lt;br /&gt;&lt;br /&gt;The Voice is horrid. &lt;br /&gt;&lt;br /&gt;And you have to see the words and touch them to get anything read???&lt;br /&gt;&lt;br /&gt;A screen reader would be simpler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3452814987779785316?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3452814987779785316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3452814987779785316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3452814987779785316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3452814987779785316'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/05/ahhhhhhhhhhh-i-just-tried-to-use.html' title=''/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-691416592428504811</id><published>2011-05-05T09:42:00.000-07:00</published><updated>2011-05-05T09:42:18.872-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='Process'/><title type='text'>Content Libertarianism</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Several months ago, one of my Web sites using Joomla got hacked. It wasn't a particularly important site, and wasn't bringing me in any money or giving me any useful exposure, so the best option was to simply drop the Joomla system and put up a holding page.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, the holding page has been up long enough, and I'm thinking through how to do the next site. The problem with Joomla, like Wordpress, Drupal, or any other software-intensive approach to deploying information, is that they degrade at a far too rapid pace to pay back the initial investment, let alone the hidden on-going maintenance costs.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are many reasons for the degradation. All software contains bugs and security holes, some of which are known by original core developers at the time you, the software user, deploy your site, but many of which are not. &amp;nbsp;Every security flaw discovered in the core software, exposes your deployed site to increased risk of hacking. That discovery process, which happens over time, immediately reduces the value of your site. You have to incur the cost of responding by updating your deployed site with newer software, which contains a whole new set of bugs and security flaws.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In turn, you potentially incur costs to deal with new bugs. If you had made fixes to bugs in the older software version, you will also incur costs to determine whether those fixes to the old bugs are still applicable... such forks to the core software must be backed out if they are incompatible.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The situation is considerably muddied by a general lack of comprehensive revision control in databases and file-system based media (giving non-repeatable and non-reversible operations), and complete absence of testing discipline in many (most?) Web software deployment strategies. The state of the machine at a given point in time is simply not knowable, so we cannot properly evaluate the impact or mitigate the consequences of changes without completely revoking them.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead, the profession has attempted to deploy even more software, layering one piece of software over another in order to monitor and control one or another aspect of the deployment. The reality is that it usually falls to individuals to act heroically, if they can, or to pay others to act heroically, which can get&amp;nbsp;exorbitantly&amp;nbsp;expensive.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When your business is on the line, people will pay such costs, but that doesn't change the fact that basically this cost of owning software is a&amp;nbsp;usury&amp;nbsp;fee... a kind of professional protection money to keep the consequences of software bugs off your business' back. The realization that something isn't intrinsically providing positive value, is what gives rise to many clients of a&amp;nbsp;feeling of being extorted. It is as if you went to a doctor to set a broken bone, only to be told that due to the way the doctor chose to set it, you'd have to return to have it reset -- every month for the next 5 years.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other reasons for the degrading include the relative unavailability of developers skilled in an idiomatic technology; the waxing and waning popularity of the supporting technologies in the "stack"; changes to public services that your system is interfaced to; the fading of the memories of the developers and stakeholders involved in making decisions that determine how the system operates and how it is structured. Most of all, the goals of the organization operating the site usually necessitate changes simply for the sake of enacting a process -- a communication cycle, performance monitoring, marketing program staging and execution -- and these all have the requirement that stuff on the site change.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We call that rather euphemistically "content management", but collectively it is really about changing stuff to do stuff that will accomplish goals.&amp;nbsp;The more stuff we can remove from that universe of discourse, the better off we'll be. &amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-691416592428504811?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/691416592428504811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=691416592428504811' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/691416592428504811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/691416592428504811'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/05/content-libertarianism.html' title='Content Libertarianism'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3734683884235831797</id><published>2011-05-04T18:02:00.000-07:00</published><updated>2011-05-05T09:43:07.938-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='Process'/><category scheme='http://www.blogger.com/atom/ns#' term='Content Management'/><title type='text'>Content Management (sic)</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;"Beware," my System's Analysis instructor warned, "of labeling anything with the word management." The rationale behind the warning is that management is a euphemism for "I don't really understand this." Like uttering profanity when you're frustrated. Or a euphemism for profanity (but you still know what you meant). Or not, but still wanting to.&lt;br /&gt;&lt;br /&gt;Content Management is one of those substitution profanities. Consultants like to throw this term around a lot, especially those whose job is to glue together processes and procedures to perform management of content. Because if you don't manage content, it will keep taking those long smoking breaks and won't be &amp;nbsp;focused enough to be productive.&lt;br /&gt;&lt;br /&gt;Lazy freakin' content. But I digress, and now I'm stooping to using lame profanity substitutions myself. The problem isn't that content lacks self-motivation, nor that it needs to be told what tasks it needs to accomplish for today. We don't even really know what content is, at least, not in any way that distinguishes it from information or data. Or stuff.&lt;br /&gt;&lt;br /&gt;Stuff Management is a more honest appellation. Since Management when applied to IT problems is most often a euphemism meaning "stuff," Content Management amounts to Stuff Stuff.&lt;br /&gt;&lt;br /&gt;I'm all for creating good abstractions, but Stuff Stuff strikes me as a little bit too abstract for practical purposes, and just a little redundant. Content Management should be jettisoned.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3734683884235831797?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3734683884235831797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3734683884235831797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3734683884235831797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3734683884235831797'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/05/content-management-sic.html' title='Content Management (sic)'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5694993087307926294</id><published>2011-02-11T04:44:00.000-08:00</published><updated>2011-02-20T05:00:19.225-08:00</updated><title type='text'>When is Lambda not a Lambda, Part 2: Replacing the Stubs</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In the Ruby programming language, there is a construct called "lambda". In answer to the second part of the apprentice's question, it is called lambda because the developers wanted to give it an air of authenticity, by identifying the construct with the computational theory of lambda calculus. &amp;nbsp;The Ruby developers weren't the first to do this, and won't be the last, and are following in a tradition among computer scientists of borrowing popular labels from one another.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Not that I know enough about the internals to tell whether or not they are justified in their use of the term lambda. What I do know is this: that anonymity has nothing meaningful to do with the computational theory, nor anything really meaningful to add in practice.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What makes lambda special, at least in Ruby, is not that it doesn't have a name. In fact, it does have an identity, otherwise Ruby couldn't pass references to a lambda around as function arguments. Ruby just hides whatever internal identity it maintains for a lambda from the user. Nor does it stop the user from assigning a lambda to a name. Anonymity is completely and utterly irrelevant to the purpose and utility of a lamba.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Where anonymity really comes into play is in the concept of a block, which in Ruby is a syntactic sugar for what other languages might call an inline function. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What makes lambda special is that the enclosing scope is bound to the lexical environment in which it is defined, and that it maintains a calling structure from which the "return" keyword will properly exit. This differentiates lambda from a&amp;nbsp;method which has a scope defined by the object to which it is bound; and from a Proc, which doesn't impose a deeper return nesting... acting as it does as a reference to the otherwise anonymous { block } syntax.&amp;nbsp;Oh, and lambda has the argument signature more strictly checked. &lt;br /&gt;&lt;br /&gt;Apparently the implementation is all based off of the kernel Proc class.&amp;nbsp;So Ruby's lambda isn't really much like its functional counterparts; like the "java" in "javascript", the name "lambda" is used more for affect than effect. &amp;nbsp;This is further highlighted by the name pollution, Y combinator gymnastics, and stack overflow surprises one gets into when attempting to use it recursively... &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On a side note, one has to give credit for the Ruby community for adding more functional language constructs. The reference implementation of Ruby 1.9 supports tail call optimization as an option.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5694993087307926294?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5694993087307926294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5694993087307926294' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5694993087307926294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5694993087307926294'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/02/when-is-lambda-not-lambda-part-2.html' title='When is Lambda not a Lambda, Part 2: Replacing the Stubs'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7578057195492358702</id><published>2011-02-11T04:13:00.000-08:00</published><updated>2011-02-11T04:14:16.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>When is Lambda not a Lambda, Part 1: Conversational Mocks</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;One of the apprentices at the office asks&lt;br /&gt;&lt;blockquote&gt;What is this thing called Lambda, and why is it called Lambda?&lt;/blockquote&gt;I'm trying to formulate a concise answer, when one of the more brilliant young developers in the office blurts out&lt;br /&gt;&lt;blockquote&gt;Lambda is just a way to make an anonymous function.&lt;/blockquote&gt;My explanation thus cut short, sticks in my throat. His quip is pleasantly succinct and sufficient to move a pre-teen on to more productive work. I'm sure I came off as ignorant and overly complicated by comparison.&lt;br /&gt;&lt;br /&gt;Except that his explanation, succinct though it was, is entirely and utterly&lt;br /&gt;&lt;h2 style="text-align: center;"&gt;W R O N G&lt;/h2&gt;not to mention misleading. Now, the kids didn't really need an explanation, and they got the sort of glossed-over, abstract re-labelling that passes for an explanation without actually being one. Like saying that what makes something a circle is that it is round. It was a mock and a stub, a convenient pretense of understanding that allowed them to conversationally move on without getting bogged down by reality.&lt;br /&gt;&lt;br /&gt;Not that he isn't capable of insightful explanations. &amp;nbsp;We're working in Ruby here. &amp;nbsp;He knows better.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7578057195492358702?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7578057195492358702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7578057195492358702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7578057195492358702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7578057195492358702'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/02/when-is-lambda-not-lambda-part-1.html' title='When is Lambda not a Lambda, Part 1: Conversational Mocks'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8667513527095650217</id><published>2011-02-10T19:52:00.000-08:00</published><updated>2011-02-11T03:57:45.454-08:00</updated><title type='text'>Curious Misunderstandings and Other Faux Pas</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Among this week's curiosities there stand out a few&amp;nbsp;weirdnesses. &amp;nbsp;Like the slamming of doors by a 46 year old woman and being left to chill with my own thoughts for the rest of the night. &amp;nbsp;Or to have a seemingly professional prospect throw a hissy fit at not being rung up in a couple of weeks, saying he doesn't want to work with me after all. &lt;br /&gt;&lt;br /&gt;Sigh.&lt;br /&gt;&lt;br /&gt;The prospect-turned-insulted-date was weird enough. It was more disquieting to have someone close throw a tantrum for having to take her own dog to a potty break for the first time in days. That'll teach me for letting them take me for granted, all right!&lt;br /&gt;&lt;br /&gt;Some people will get the wrong impression about you simply because they lack the empathy themselves to see things from your point of view. But it helps no one to be too agreeable too often.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8667513527095650217?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8667513527095650217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8667513527095650217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8667513527095650217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8667513527095650217'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/02/curious-misunderstandings-and-other.html' title='Curious Misunderstandings and Other Faux Pas'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7229748537156097834</id><published>2011-02-10T03:20:00.000-08:00</published><updated>2011-02-10T03:20:20.309-08:00</updated><title type='text'>Why, Again</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I've felt recently that I'm picking up new skills; still questioning the pace at which I pick them up, and why it seems frustratingly slower than those around me. I'm a loner, to be sure, not by conscious choice but apparently by the side-effects of internal preferences and tendencies as yet beyond my ken. Not that I feel alone in this... there are many who appear to be alone and just don't see it.&lt;br /&gt;&lt;br /&gt;I have trouble following in conversation, in being where everyone else is being, doing what everyone else is doing. It is as if, if someone else is already there, squatting and tearing up the soil, I need to be elsewhere. Not sure why that is, or from whence it stems, but yeah, it has been with me since I was a little kid.&lt;br /&gt;&lt;br /&gt;One aspect of this tendency to take a side-long view of social interaction, is that I'm constantly asking "Why"? &amp;nbsp;And the more focused I get on a single skill area, the more strongly that question pervades my thinking -- why is this a worthwhile technology, why will it be useful to struggle with what seems to be the gratuitous constraints it imposes, why am I focused again on technology when it is the social interaction that is most obviously my own stumbling block, and why is it that I am not profiting sufficiently personally or professionally from either my skills or relationships ?&lt;br /&gt;&lt;br /&gt;But the most important question "why" seems to be pointed at everyone else... my peers... why are you doing what you are doing? &amp;nbsp;Sean Hannity reminded me of this on his radio show. As I flipped on the drive home, I caught the tail end of a conversation about him confronting a businessman over taking&amp;nbsp;stimulus money.&amp;nbsp;He remarked that as a former construction worker, it would have violated his sense of ethics to build an abortion clinic building even if it was well funded. &amp;nbsp;To me, it isn't whether or not a customer is "being made happy," it is whether what we are pursuing should be done at all.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7229748537156097834?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7229748537156097834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7229748537156097834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7229748537156097834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7229748537156097834'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/02/why-again.html' title='Why, Again'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8089690754655709849</id><published>2011-02-05T04:48:00.000-08:00</published><updated>2011-02-05T04:48:47.314-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Iron Filings</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;blockquote&gt;&lt;div style="text-align: center;"&gt;Iron by iron is sharpened, And a man sharpens the face of his friend.&lt;/div&gt;&lt;/blockquote&gt;A minor incident this week reminded me of this proverb. Actually, a lot of incidents do. As a metal blank is turned into a usable tool, it must first be shaped, then smoothed, and finally polished. Likewise, older tools can be refurbished by first welding, then re-grinding and polishing. In the process a lot of little bits of metal castings are generated, the stuff that was useful at some moment in time but now goes completely against the grain of the refurbishment.&lt;br /&gt;&lt;br /&gt;My hope is to be able to find a path that makes me feel that I'm not constantly leaving great big piles of "me castings" around on the floor. &lt;br /&gt;&lt;br /&gt;The other day, I cut some code for a Rails report. Relatively simple stuff. But there were a few problems. First, I was fatigued. Second, I was programming alone. These contributed to the actual root causes, the "me castings" for this week:&lt;br /&gt;&lt;br /&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Short-cutting tests is just a way to lull yourself into a false sense of security. Run them the way they are supposed to be run, completely, from top to bottom, and pay attention to the details of what the results are saying. Make sure you run tests fully before attempting to commit changes.&amp;nbsp;&lt;/li&gt;&lt;li&gt;When you have a failing test, don't commit. Or if you do commit, make it clear to everyone involved that you have failing tests, and ask for help; or offer to commit to a branch; or stash the changes and move on momentarily until you can get help.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;Line-wise and paragraph-wise Cut and Paste is a recipe for error injection. It is just dangerous, period. I used to code by cut-and-paste often in 4GL languages due to the&amp;nbsp;repetitiveness of the apps' boilerplate approach to development. I foolishly thought I could use it and find a way to not inject errors. The lesson, in retrospect, is that there is no way to separate cut-and-paste errors from cut-and-paste. Copying lines and paragraphs is especially evil because my brain tends to be looking for and see the similarity, and auto-correct for the differences, but those corrections may never make it to my fingers. &amp;nbsp;Besides, the approach to Rails used here is most definitely not a boilerplate approach: the app may be copied to start, but everything after that is treated as one-of crafting. &lt;i&gt;This was the most grievous "me casting" of the week.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Cutting into other's code requires special mindfulness. Doing it with cutting-and-pasting is completely wrong. Doing cutting-and-pasting while tired is a crime. At one point, I saw what looked exactly like a three-line function I just wrote, &amp;nbsp;so I cut. &amp;nbsp;It wasn't my function, and had I run Rake properly I would have seen that it was not. Fortunately, we had git.&amp;nbsp;Make sure you communicate if you have an elusive sense of uncertainty, but &lt;i&gt;especially&lt;/i&gt; if you feel completely confident.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;I'm tempted to force git to warn me had I not run Rake before committing, or obfuscate the line-oriented cutting commands in Vim, but these are mere technical crutches. The reality of the examples of practice that I'm seeing, is that it forces you to be mindful of your surroundings, of your code, of your peers.&lt;br /&gt;&lt;br /&gt;Being mindful enough of the affect of your actions, and communicating often and early with those in your circle, is critically important. At least, if you want to stay in the circle. It has been many years since I've been in a group of developers that really functioned as a team. It is profoundly disturbing to see how much less proficient I can be compared to some of the younger developers, and as difficult to consciously spot and let go of poor habits. But I am trying.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8089690754655709849?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8089690754655709849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8089690754655709849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8089690754655709849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8089690754655709849'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/02/iron-filings.html' title='Iron Filings'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-1180991514190830328</id><published>2011-01-25T21:26:00.000-08:00</published><updated>2011-01-25T21:30:57.392-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Social Networking'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Is Consulting Like Dating?</title><content type='html'>If so, it really explains a lot.  The tech republic has a blog entry that &lt;a href="http://www.techrepublic.com/blog/project-management/keeping-the-client-relationship-fresh/2141"&gt;goes all pedantic about the simile&lt;/a&gt;, but there is at least the illusory feeling of truthiness to it. &lt;br /&gt;&lt;br /&gt;I never dated as a kid. As a teen I think I had one date, and it went nowhere. Truth is, I didn't know what was expected of me in social situations then, and more or less still don't now. &lt;br /&gt;&lt;br /&gt;The article starts off with, "keeping clients happy may be similar to keeping your significant other interested," which strikes me as ironic and a little funny given that most married folks in the US end up divorced.&lt;br /&gt;&lt;br /&gt;Well, I tried to bend over backwards to keep people happy. It doesn't work, for them or for me. So when a recent prospect complained to a mutual friend that I was a "dead end," because I hadn't been in contact for three weeks, at first I was a little bit taken aback and afraid that something I had not done was unprofessional and had spoiled the relationship. &lt;br /&gt;&lt;br /&gt;Then I realized, we don't have a relationship, that prospect and I. We never did. She said she'd be in touch, but expected me to be banging down her door. She wanted me to tell her I had free hours I did not have. She complained to her friend instead of probing me back. She wanted me to dance, and I'm not a dancer. &lt;br /&gt;&lt;br /&gt;I understand. I know there are many people far more successful than myself because they do the dance, they have a knack of schmoozing and persuasion. Those were skills that at first I merely lacked, but then consciously eschewed.  It was not just a recognition of how much effort was wasted, or that the cost to me personally of trying to do that dance was too exhausting. &lt;br /&gt;&lt;br /&gt;It was the false premise of it, the inert fakery sitting behind the outward countenances, and the desire of seemingly nice people to take advantage of your openness. It does not excite me to be constantly mindful to probe and prod clients constantly when I'm solving technical problems. &lt;br /&gt;&lt;br /&gt;And when my own family members aren't interested in talking to me, worrying about whether I'm stroking a client's ego frequently enough just isn't on my list of priorities.  Frankly, the prospect complaining to her girlfriend told me a lot about her style of communication and her own ability to think straight, and it isn't good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-1180991514190830328?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/1180991514190830328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=1180991514190830328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1180991514190830328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1180991514190830328'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/is-consulting-like-dating.html' title='Is Consulting Like Dating?'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7978782954105988511</id><published>2011-01-25T04:41:00.000-08:00</published><updated>2011-01-25T05:51:49.040-08:00</updated><title type='text'>Acting like a consultant</title><content type='html'>This week-end I had a small verbal slap on the knuckles reminder that acting like a programmer is not sufficient to be a good consultant. It is difficult for some of us to come up from the sea of hardware and software and breath, and in the meantime people can feel abandoned or ignored. &lt;br /&gt;&lt;br /&gt;Truth is, my boldness comes in fits and starts, and it is difficult for me to maintain constant communication with my network. It is complicated by my personality, but it isn't &lt;blockquote&gt;who I am&lt;/blockquote&gt;, it is rather a skill that, in practice, I haven't mastered. &lt;br /&gt;&lt;br /&gt;On the other hand, I find that it terribly distracting to be thinking about who I need to contact, keep their particulars in my head, and think proactively about their situations. I have to block the social aspects out of my mind while I'm programming, otherwise everything blurs. &lt;br /&gt;&lt;br /&gt;Thinking like a consultant has other differences from programming in the raw:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Strategic thinking versus an "order taking" mentality&lt;/li&gt;&lt;li&gt;Dialog versus top-down communications&lt;/li&gt;&lt;li&gt;Probing for needs versus accepting plans as communicated&lt;/li&gt;&lt;li&gt;Asking questions to build a strategic understanding instead of focusing on tactical steps&lt;/li&gt;&lt;li&gt;Build a working context of the client's business: how they generate income; how they differentiate themselves from competition; industry shifts; customer and employee issues; the problems at hand and the client's objectives &lt;/li&gt;&lt;li&gt;Leading the discussion and influencing it to set expectations&lt;/li&gt;&lt;li&gt;Keeping the dialog going (this is a pain point for us programming types!)&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/1095111220804824515-7978782954105988511?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7978782954105988511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7978782954105988511' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7978782954105988511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7978782954105988511'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/acting-like-consultant.html' title='Acting like a consultant'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6533382168706753397</id><published>2011-01-22T03:13:00.000-08:00</published><updated>2011-01-22T03:13:23.446-08:00</updated><title type='text'>Hobos hacking on Rails</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Testing my newly found programming confidence, I started hacking up an example survey form for a client. I tried Hobo, which led to some interesting observations about what Agile really means. &lt;br /&gt;&lt;br /&gt;One moment my sample app was working, the next it was not. The problem was that I had generated a resources controller and model combination with a name that Rails did not like. &lt;br /&gt;&lt;br /&gt;I checked over the model names and use ack to search for deviances. Convention over configuration, they say, except that nothing appears to be deviating. Somewhere along the line something got mixed up, and now it doesn't just work. Instead it broke the whole application. &lt;br /&gt;&lt;br /&gt;Well, that points up a couple of ugly properties of Rails apps. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Small changes have an application-spanning impact&lt;/h2&gt;&lt;br /&gt;Pre-Web languages, such as C and Perl, have their issues with program structure and encapsulation, but Ruby on Rails (and other Web frameworks) have nothing to write home about in this respect: it is &lt;b&gt;trivially easy to expose your system to breakage&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;The thing Rails does right is to help ensure that such changes don't get pushed out to production. That's the test-first methodology. The thing it does wrong is a feature: the use of English language part-of-speech heuristics to create mappings amongst the MVC components. It gets it wrong about 10% of the time, that is to say, I get it wrong but the framework makes it easy to do so and hard to spot the location of the incorrect guesswork. &lt;br /&gt;&lt;br /&gt;I'd rather not have to keep fixing the 10% or so times when the heuristics don't match the way I want to phrase the solution.  But heuristic gaps are correctable; the persistent itch is that the framework wants to tell me to stick to a formula but hides all the wiring that would tell me where and how I'm crossing the lines, and translates tiny errors into epic fails. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A System That Uses HTML Is Not A Hypertext System&lt;/h2&gt;&lt;br /&gt;MVC frameworks are not really Web application frameworks but application frameworks that utilize the syntax of Web technologies to communicate. That is &lt;i&gt;not&lt;/i&gt; easily correctable by slight alterations in practice. &lt;br /&gt;&lt;br /&gt;State representations and transitions in a Rails app are all wired up through explicit code. Each entity is identified by a row number and associated by integer relations (this management strategy is &lt;b&gt;reminiscent of DBase&lt;/b&gt;, but what "relational database" means and how Rails isolates the database layer is another discussion altogether). MVC uses views that spit out markup, but in themselves, views do not comprise state representations.  &lt;br /&gt;&lt;br /&gt;The RESTful Web uses links to stepping through the state space, and delivers markup documents that embody the current state representation along with the transition paths. That takes a kind of markup calculus to implement. Although Rails attempts to derive MVC patterns and hides a lot of its complexity in convention and meta-programming, there is an essential difference in the level of logic at play in the reduction of a solution. &lt;br /&gt;&lt;br /&gt;A url format does not makes a system RESTful. A framework that stores almost all but not quite everything in sessions, and wires up features in point-to-point coding is doing what amounts to a Web algebra. That is very un-RESTful.  Rails is on the top of the MVC heap, but what MVC platforms do is a little of the wrong sort of bespoke calculus mixed with a lot of idiomatic algebraic logic. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Bottom Line&lt;/h2&gt;&lt;br /&gt;MVC platforms are more than a slight inductive mismatch to the RESTful archetype. In my humbler opinion, REST requires a comprehensive markup calculus to accomplish.  An effective REST platform should provide comprehensible algebraic representations and coherent integration and derivation techniques that do not require nail-up code to implement, conventions not withstanding. &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6533382168706753397?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6533382168706753397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6533382168706753397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6533382168706753397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6533382168706753397'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/hobos-hacking-on-rails.html' title='Hobos hacking on Rails'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2375126078186187378</id><published>2011-01-18T17:17:00.000-08:00</published><updated>2011-01-18T17:17:47.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pith'/><title type='text'>Recent proverbs, aphorisms, and admonishments</title><content type='html'>&lt;dl&gt;&lt;dt&gt;Never interrupt an interrupt.&lt;/dt&gt;&lt;dd&gt;If you don't understand this, you may be functionally ADD.  &lt;ul&gt;&lt;li style="list-style-type: none;"&gt;Me: "Do you know what that means?"&lt;br /&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;She: "No."&lt;br /&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;Me: "_That_, is why you fail."&lt;br /&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;She, laughing: "No, sir, that is why I succeed."&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;From experience, I can tell you she lets her interruptions get interrupted all the time. One might also suppose that it is bad to stack interruptions, or shuffle them around, but let's not bend the metaphor too much lest it break and we expend too much time picking up little pieces of interruptions all about us. &lt;/dd&gt;&lt;dt&gt;Organized like scrambled eggs&lt;/dt&gt;&lt;dd&gt;My son suggested this simile after attempting to design landscapes with a group on an online game called Minecraft. It applies well to the domain of programming. Ad-hoc development, whether coding, Minecraft landscape layout, or any other design regime and medium, all share common characteristics... what seems organic and natural at first may quickly decompose into an amorphous slurry of mush. &lt;/dd&gt;&lt;dt&gt;Code Grieving&lt;/dt&gt;&lt;dd&gt;Another anti-social pattern observed in Minecraft, and doubtless other online simulacra. A "griever" is a game player who rather purposefully destroys other peoples' creative efforts. By analogy, a code griever is a peer who, without acting collaboratively, breaks down working code that is already there. (Pair programming can sometimes feel as if you are being grieved, but it isn't the same phenomena.)&lt;/dd&gt;&lt;dt&gt;Vanity of vanities. All is vanity.&lt;/dt&gt;&lt;dd&gt;Explaining that wouldn't be worth the effort.&lt;/dd&gt;&lt;/dl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2375126078186187378?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2375126078186187378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2375126078186187378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2375126078186187378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2375126078186187378'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/recent-proverbs-aphorisms-and.html' title='Recent proverbs, aphorisms, and admonishments'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7000916576782477183</id><published>2011-01-17T22:05:00.000-08:00</published><updated>2011-01-18T16:37:02.231-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Minimal Viable Specification</title><content type='html'>Every now and again you get to see glimpses of how people think in the way they formulate and frame up a discussion, that tells you they obviously adopted language from someone who did not think as they did. Such is the case with the term "Minimal Viable Product".&lt;br /&gt;&lt;br /&gt;The term is remarkably similar to&amp;nbsp;euphemisms for unborn babies [er, "fetuses"]. It invokes a metaphor of a gestating product, which might be aborted should it fail to exhibit a minimal feature set. &amp;nbsp;I personally find the term to be in poor taste, and more than slightly stupid in assuming requirements form a static set over which you can assess a minimum.&lt;br /&gt;&lt;br /&gt;Nevertheless, it is commonly used in Agile/Lean circles. &amp;nbsp;Transitively and reflexively, one might ask the question of why there is then no "Minimal Viable Specification". It is not a foregone conclusion that a system must be&amp;nbsp;over-specified&amp;nbsp;before building can proceed, but neither is it an obvious truism that a stream-of-consciousness approach to coding gives the best value proposition to the client.&lt;br /&gt;&lt;br /&gt;A minimum viable product implies that a set of coherent requirements could have been envisioned at some scale, while some who use the term often advocate explicitly against just such specifications. &amp;nbsp;I understand why: as programmers, we get paid to code, not to specify. Well, sort of. &amp;nbsp;Maybe, maybe not.&lt;br /&gt;&lt;br /&gt;I've also heard it said that the code _is_ the specification. Or that the tests in TDD/BDD are the specifications. While these arguments have merit from the programmer's perspective, they are arcane and continue to sound weak from a customer's viewpoint -- at least as far as the tests or code don't rise to the level of abstraction that the customer's brain is at.&lt;br /&gt;&lt;br /&gt;Einstein is widely credited with saying that things should be as simple as possible but no simpler; yet it was Newton hundreds of years before who was able to practically refract white light and recompose them again... thereby demonstrating that the most apparently simple of colors is also a composite and the most complex colors of all. &amp;nbsp;The trouble with scientists is that sooner or later a few of them will make inconvenient things like facts get in the way of conveniently wrong abstractions. The trouble with reality is that it doesn't respect Agile ad-hoc abstractions and just keeps on behaving the same whether you believe in it or not.&lt;br /&gt;&lt;br /&gt;So I posit that there is some minimal specification that really does need, in effect, to be professionally drafted and validated, else someone is taking too much risk, paying too much money, and/or just getting suckered into a co-dependent relationship with coders. &amp;nbsp;Not that I pretend to know what that minimum is, I am just suggesting that it must exist, and the tangible artifacts representing it should consist of more than just a few notes taken while schmoozing with a client.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7000916576782477183?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7000916576782477183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7000916576782477183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7000916576782477183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7000916576782477183'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/minimal-viable-specification.html' title='Minimal Viable Specification'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6731691596847804188</id><published>2011-01-17T21:23:00.000-08:00</published><updated>2011-01-17T21:24:03.147-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Hobo'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='Rails'/><title type='text'>Different Shades of Grey</title><content type='html'>I just spent some time finishing cleaning up my gemsets, and re-installing Bundler, per my earlier posting about using RVM. &amp;nbsp;In all, I have three distinct Rails applications set up in my workspace right now, each with a slight variation on the technology stack:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Rails 3 and Ruby 1.9.2&amp;nbsp;&lt;/li&gt;&lt;li&gt;Rails 3.x and Ruby 1.8.7 and Hobo 1.0.3&lt;/li&gt;&lt;li&gt;Rails 2.3.5 and Ruby 1.8.7 and Hobo 1.0.2&lt;/li&gt;&lt;/ol&gt;Using the "put everything in @global" approach worked OK for (1) alone, but when (2) and especially (3) came along, Bundler got downright confused about which Rails to run even though it knew which one was supposed to have been installed and which version was called out in the Gemfile.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two failure modalities were found. First, even though the Ruby version-specific global gemsets had been emptied, the 1.8.7 global gemset had inadvertently been repopulated by an errant bundle install. &amp;nbsp;Second, neither that gemset nor the app-specific gemset contained the Bundler gem itself, which had been silently "adopted" from the enclosing (system wide) environment. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The solution was to reset... go back and clear out the gemsets like I had before, and this time make sure the app-specific gemset had been properly selected before running gem install bundler and then bundle install.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Incidentally, how you start the server depends, but it seems that there are at least two ways :&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;script/server&lt;/li&gt;&lt;li&gt;rails server&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I guess I don't know enough about the blessed way of Ruby server zen, but it certainly wasn't obvious by looking at the files sitting in the local directory.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6731691596847804188?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6731691596847804188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6731691596847804188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6731691596847804188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6731691596847804188'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/different-shades-of-grey.html' title='Different Shades of Grey'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7704297054983941325</id><published>2011-01-10T15:17:00.000-08:00</published><updated>2011-01-10T15:17:00.982-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>Pretending Javascript has Object Orientation</title><content type='html'>Suppose I have a Prototype.js class:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var Parent = Class.create({ &lt;br /&gt;initialize: function() {... }&lt;br /&gt;invariantProcess: function() { &lt;br /&gt;this.part1();&lt;br /&gt;this.part2();&lt;br /&gt;},&lt;br /&gt;part1: Prototype.emptyFunction,&lt;br /&gt;part2: Prototype.emptyFunction,&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and a subclass&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var Child = Class.create(Parent,{ &lt;br /&gt;initialize: function($super) { $super... }&lt;br /&gt;part1: function() { ... draw part 1 ... },&lt;br /&gt;part2: function() { ... draw part 2 ... },&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ordinarily, inheritance and virtual dispatching allows us to override part1 and part2 without touching the invariantProcess in the base class. This often fails in Javascript as an indirect side-effect of the fact that classes are library constructs, not first-class objects. &lt;br /&gt;&lt;br /&gt;In Javascript, what is commonly called "inheritance" is actually just copying properties around instances and instance prototypes, and names in method bodies are lexically bound to the scope in which the method is defined. &lt;br /&gt;&lt;br /&gt;None of that is a bad thing. The bad thing is when you take a second-class method and treat it as if it were an independent function. This can happen, for instance, when you pass the method as a callback function. The bindings can get botched, with names either undefined or bound to the wrong object. In the example above, "this" might not be the "this" that we want it to be. &lt;br /&gt;&lt;br /&gt;I ran across this recently while creating Prototype.js class wrappers for a Processing.js example. Processing expects a callback that will bind a drawing function to the library, but when a method is used as the callback it can horribly ugly to get the bindings correct. &lt;br /&gt;&lt;br /&gt;The solution generally amounts to using a Factory pattern, returning a new function with the critical variables defined in the enclosing scope. This all but rules out using methods directly, which then take the role as supporting functions instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7704297054983941325?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7704297054983941325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7704297054983941325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7704297054983941325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7704297054983941325'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/some-days-i-hate-pretending-javascript.html' title='Pretending Javascript has Object Orientation'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8143802698343501494</id><published>2011-01-08T07:58:00.000-08:00</published><updated>2011-01-10T08:56:15.832-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Hobo'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><title type='text'>More hoboization</title><content type='html'>I was playing with Processing.js and decided that it would be easier to use a Rails server to fiddle with the prototypes than installing an apache server or ftping to a host. &amp;nbsp;So I returned to one of my trial apps, leapercan, and tried to run the server. &amp;nbsp;It bombed out.&lt;br /&gt;&lt;br /&gt;Yet I hadn't touched that code tree! When side-effects happen &lt;i&gt;just because&lt;/i&gt;,&amp;nbsp;is an obvious sign that you have violated (or never adopted) the axiom of closure. I happen to think closure is a good thing in general, when you can get it. I'd much rather trade extra disk space to get it than my time in debugging strange errors.&lt;br /&gt;&lt;br /&gt;It happens that we use RVM, the Ruby Version Manager. We also use Bundler. What we haven't been using is RVM's Gemsets. Other developers with whom I've been pairing with over the past few months maintain a practice of always using the @global gemset, and use Bundler to maintain the gems. In this practice, RVM is relegated to maintaining only distinctive Ruby versions. &amp;nbsp;This is supposed to work in theory because Bundler version control for the gems used by an application.&lt;br /&gt;&lt;br /&gt;The root cause for the failure? &amp;nbsp;My Leapercan application was based on Hobo 1.0.x, using Rails 2.x and Ruby 1.8.7. With a Splotchup application I tried out Hobo 1.3.x, using Rails 3.x and Ruby 1.8.7. Starting to see the trouble yet?&lt;br /&gt;&lt;br /&gt;Bundler is fine for fetching and installing specified versions of gems. But in practice I have found that it did not maintain two different versions of the same gem, each for a different application. I'm told that it should, and that the ".lock" file should fixate the versions of the gems in use. But when I switched my working context, things just broke. My working hypothesis is that my Gemfile did not specify a version for some gems, and the use of a single gemset allowed bundling from one app to affect the gems v another app.&lt;br /&gt;&lt;br /&gt;Using @global gemset is a good idea when you run a single Ruby version for a single application, and want to save space. It is a bad idea otherwise.&lt;br /&gt;&lt;br /&gt;My solution? Impose closure. I don't care if I lose a little, or a lot, of disk space with separate gem copies. I want my application development and source tree completely and utterly self-contained and self-consistent. The way to accomplish closure is to get rid of global defaults and spurious sharing.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Don't rely on the System ruby. Unfortunately, if you've done anything interesting already you'll have to hack some directories to get rid of the system gems. Ironically enough Mac OSX lacks even a half-baked GUI for managing system add-on components. It would be better to fix RVM to avoid the real problem, which is that it does not sandbox out the system gems, but I had already done the removal before thinking of that approach.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo mv /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8 \&lt;/code&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8.default&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;sudo mkdir &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8&lt;/span&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Use RVM to install each Ruby version you will use&lt;br /&gt;&lt;code&gt;&lt;br /&gt;rvm install 1.8.7&lt;br /&gt;rvm install 1.9.2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;For each application, create a gemset; empty the global gemset for the ruby it will use.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;rvm use 1.8.7&lt;br /&gt;rvm gemset empty global&lt;br /&gt;rvm gemset create splotchup&lt;br /&gt;rvm gemset create leapercan&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When you start developing, switch to the gemset automatically&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd ~/workspace/splotchup&lt;br /&gt;echo "rvm use ruby-1.8.7@splotchup" &amp;gt; .rvmrc&lt;br /&gt;&lt;br /&gt;cd ~/workspace/leapercan&lt;br /&gt;echo "rvm use ruby-1.8.7@leapercan" &amp;gt; .rvmrc&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Install Bundler, then let Bundler take care of the rest; avoid using gem to install gems other than initially installing bundler.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd ~/workspace/splotchup&lt;br /&gt;gem install bundler &amp;nbsp;# if you haven't already&lt;br /&gt;bundle install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;cd ~/workspace/leapercan&lt;br /&gt;gem install bundler&lt;br /&gt;bundle install&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you maintain different mainline branches of development (an unnecessary complication in my book), create and use a corresponding empty gemset.&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;There now. My apps are completely isolated from one another. A purist might object that I'm duplicating a lot of code here, but there are two answers to this:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;code&gt; &lt;/code&gt;&lt;/ol&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;So What? Most ruby gems are small. The supposed space saving is a false economy, since the bugs introduced by violating closure cost much more.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;There is no duplication and this is not a violation of DRY. Application-specific gemsets are necessary and sufficient because the gems are a factorable part of the application source, not universal attributes of the environment.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8143802698343501494?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8143802698343501494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8143802698343501494' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8143802698343501494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8143802698343501494'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/more-hoboization.html' title='More hoboization'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6559911038006507316</id><published>2011-01-01T11:16:00.000-08:00</published><updated>2011-01-01T11:17:24.729-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Knowledge is not infinite; neither is ignorance</title><content type='html'>A FB friend posted a quote by Zhuang Zi,&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Life Is Finite, While Knowledge Is Infinite.&lt;/blockquote&gt;&lt;div class="mvm uiStreamAttachments clearfix" data-ft="{&amp;quot;type&amp;quot;:&amp;quot;attach&amp;quot;}" style="color: #333333; display: block; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 12px; margin-bottom: 10px; margin-top: 10px; zoom: 1;"&gt;&lt;div class="UIImageBlock clearfix" style="display: block; zoom: 1;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Thing is, words have meaning, and those many meanings that words can have may be unbounded. Yet while &amp;nbsp;unbounded implies pluralities it certainly doesn't necessitate infinities. The real difficulty here is that we neglect an operational definition for knowledge, one that allows us to allocate our ignorances wisely.&lt;br /&gt;&lt;br /&gt;Knowledge poses an interesting term in this respect, because we so often conflate the many meanings to the point that the word itself barely means anything distinguishable. &amp;nbsp;To Zhuang Zi, knowledge is certainly not a trait wholly attributable to humans, else his quote would be silly on its face. Zhuang's knowledge exists outside of Life, something to be pursued yet which is unfathomable.&lt;br /&gt;&lt;br /&gt;On the other hand, what is knowledge if it is not known by a knower? The true knowledge of every man perishes with him, whether he be an author or a ditch digger, rich or poor, wise or foolish. &amp;nbsp;Without a knower, our thoughts may be meta references to that we don't yet know; they may be delusions, or &amp;nbsp;dreamlike feelings reverberating in our skulls affirming that we know when really, we don't.&lt;br /&gt;&lt;br /&gt;It is the arrangement of neural inter-patternings enabling imagining of our universe including concepts such as "other" and "self" that we call knowledge. Those patterns are complicated. Numerous. Interdependent. But not infinite. It is that finitude that allows us to learn, make practical generalizations, and to reframe and parameterize our understanding.&lt;br /&gt;&lt;br /&gt;While the experiences that are thrown at society in general and us in particular are unbounded, &amp;nbsp;they induce knowledge if and only if they alter someone's brain chemistry; and that knowledge only remains around as long as those brains retain their altered states.&amp;nbsp;In effect, our brains are big self-mutating hash functions, funneling those experiences from an infinity of infinities down to a countable set of neural patterns. And like any hash function, the pigeonhole principle rules.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6559911038006507316?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6559911038006507316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6559911038006507316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6559911038006507316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6559911038006507316'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2011/01/knowledge-is-not-infinite-neither-is.html' title='Knowledge is not infinite; neither is ignorance'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8053968057927854931</id><published>2010-12-31T15:38:00.000-08:00</published><updated>2010-12-31T15:38:21.052-08:00</updated><title type='text'>Using Hamachi for Remote Desktop Sharing</title><content type='html'>I, or more correctly one of my clients has used GoToMyPC before to share their PCs for support purposes. I am not in the PC support business so it isn't something I care too much about, but sometimes I do get curious about alternatives.&lt;br /&gt;&lt;br /&gt;One alternative is LogMeIn. Definitely lower cost. If you are a gamer or non-profit, some of their products and services are provided without fees. That's actually something a few people and organizations I know of would benefit from.&lt;br /&gt;&lt;br /&gt;The first free thing is the LogMeIn Free service. Even the Pro version is not at all pricey. LogMeIn Free gives you most of the interesting things of GoToMyPC, without the cost. If you still need to share files, you can always use DropBox or one of the other fine sharing services.&lt;br /&gt;&lt;br /&gt;The second free thing is what would appeal to hobbyists, gamers, and some non-profit IT types: the Hamachi Virtual Private Network. &amp;nbsp;You download a little pop-up utility that lets you connect to another computer also running Hamachi, or host a connection. &amp;nbsp;They call it "mesh" network, but it is basically peer-to-peer networking.&lt;br /&gt;&lt;br /&gt;One neat thing about Hamachi is that you can also use it to tunnel Windows Remote Desktop Connections or VNC connections. Create a network on one of the Hamachi clients and connect to it on the other client. After that you can use any RDC client to connect to a Microsoft Windows PC or VNC to connect to a Linux, Mac, or PC client, using the IP address that Hamachi shows in its pop-up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Don't forget to grant access to Hamachi in your software firewall and through your router's firewall. Also, Windows users will have to enable RDC sharing and set a password for it in their control panel.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;As I write this, I'm connected through Hamachi to my Lenovo T61, and running RDC to access the Windows desktop. It is on my local LAN, so performance is not representative, but it is neat that it can be done, effectively making it unnecessary to use LogMeIn or GoToMyPC at all for non-commercial purposes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8053968057927854931?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8053968057927854931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8053968057927854931' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8053968057927854931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8053968057927854931'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/using-hamachi-for-remote-desktop.html' title='Using Hamachi for Remote Desktop Sharing'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5475036659365173616</id><published>2010-12-29T22:12:00.000-08:00</published><updated>2010-12-29T22:12:16.710-08:00</updated><title type='text'>Classes and Inheritance in Javascript</title><content type='html'>Here is some news for Javascript monkeys: Javascript does not have classes. None. Nada. When people speak of OOP classes and Javascript, they are making it up, literally.&lt;br /&gt;&lt;br /&gt;Any talk of OOP classes in Javascript code is a pretense. Now, some of that code is really ingenious, really nifty stuff. But there are no first-class classes in Javascript.&lt;br /&gt;&lt;br /&gt;There are two consequence of these non-first-class constructions:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Core language primitives were designed before the faked constructs existed and although the core language retains its closure (as much as before the extensions), the faked constructs introduce new elements and relationships that are not necessarily conserved through the primitive operations.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The extended constructs do not necessarily meet the same algebraic axioms; the library may not entirely consistent within itself.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;A typical case is the use of JSON to send around objects which use library-based inheritance frameworks. It is easy to reconstruct the property sets, but difficult to ensure that the invariants assumed by your class framework remain invariant after a round trip.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5475036659365173616?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5475036659365173616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5475036659365173616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5475036659365173616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5475036659365173616'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/classes-and-inheritance-in-javascript.html' title='Classes and Inheritance in Javascript'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4643520153149691058</id><published>2010-12-27T19:19:00.000-08:00</published><updated>2010-12-27T19:19:41.599-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Another birthday past</title><content type='html'>I turned 47 today. It wasn't the birthday I might have hoped for, but it doesn't seem like I could have expected much more.&lt;br /&gt;&lt;br /&gt;The weather was rough this week-end, but the roads were mostly clear and I planned on going in for a half day at least. My son wanted me to drop him off at a buddy's house, which meant he wouldn't be home. His mom asked me, obliquely, if I had wanted to drive her to work, to which I replied not really and made an unwise remark about what a wise aleck she was being. She called me a jerk, and left a bit later. On my drive out my son wished me a happy birthday, which was poignant. So that was how my day started.&lt;br /&gt;&lt;br /&gt;I went in to work for the morning. Nothing special, just some debugging to figure out why someone else's home-brewed JSON parser wasn't actually doing the right thing by failing to properly initialize Prototype.js object's base classes. I figured it out but it didn't get fixed. It is not my place to set that priority as yet, but still -- it is the difference between doing the right thing and making things work for right now, that can bite you later when you are no longer looking. Deserialized objects should always be constructed the same way any other instances of classes are; anything else is a proximity fuse code mine. &amp;nbsp;So that was the second part of the day.&lt;br /&gt;&lt;br /&gt;Plans to have lunch with a friend were interrupted at the last minute due to fear of the previous weekend's weather. I don't blame my friend, but it was unexpected and I was looking forward to having a good conversation. &amp;nbsp;Instead, I spent much of the rest of the day alone. I took a late lunch out and chatted with the restaurant owner, but it wasn't the same. I read up on Hobo and got a Jasmine gem to install properly, and looked over how JSON should (really) deserialize... finding that people don't seem to do it right at all in most cases, at least not with respect to higher-order class/inheritance constructions implemented at the Javascript library level. It continues to amaze me that people do mud-pie programming in Javascript and pretend that there is rigor and soundness to what they are doing. So that was the third part.&lt;br /&gt;&lt;br /&gt;Checking messages, a few people wished me a happy birthday. My mom, her sister, and my sister called to say the same. That's nice. Not unimportant, but they all seem so... distant. Well, they are distant, but we don't really have much in the way of enriching conversation going on either.&lt;br /&gt;&lt;br /&gt;Later, my wife got home early, and needed to vent about the goings on at her place of employment. Lots of dishonest communication in the workplace, compounded by a general lack of integrity, unrealistic goals, and hidden agendas, make it pretty rough for people to have a satisfying workplace life. When management and practitioners accept false premises for arguments, the fallacies inevitably compound and accumulate like waves cresting and crashing back upon a beach. It wears you down personally, and slowly undermines whatever solid thing you do manage to build. I got to hear about it, and offer consolation and comfort.&lt;br /&gt;&lt;br /&gt;She got me a present too, a ceramic grinder because I grind nut mixes. Nice thought, but it was from the local mall and, as it happened, gummed up within about a minute. OK for fat-free things maybe, but not nuts and cocoa beans. I spent the next hour cleaning it out carefully before re-wrapping it for a return. I thanked her for it, but given the price (over $60) it did not seem like a keeper.&lt;br /&gt;&lt;br /&gt;She put the TV on. I've come to hate TV. It isn't my choice of spending any evening, let alone my own birthday. It is icy out now, the roads are dangerous, so there is no going out. I lay down on a love seat in the other room to reflect on the day.&lt;br /&gt;&lt;br /&gt;She puts the dog out and goes to bed early, not saying much otherwise. She doesn't seem to be angry or bothered in any way, just indifferent. Sigh.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;I wonder how to improve upon what seems like a completely hideously unsatisfying social life. I mean, seriously - being alone all day??? &amp;nbsp;It isn't reasonable. It isn't healthy.&amp;nbsp;It just isn't right.&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Blogging about it seems like a good enough idea, at least to help me reflect. &amp;nbsp;I wrote once before about analogies in fiction, how there are often disturbingly concrete mappings to reality. Today was a day in the life of Robinson Crusoe. I tilled the soil, planted corn, minded my traps, said my prayers, and spent the balance of my time thinking about what else I could do to improve my situation and do more than merely survive in isolation.&lt;br /&gt;&lt;br /&gt;Normally that would be enough, but today was sad and lonely, and here at the end of the day I'm just glad to say it is over.&lt;/div&gt;&lt;blockquote style="text-align: justify;"&gt;And I have seen that there is nothing better than that man rejoice in his works, for it is his portion; for who doth bring him in to look on that which is after him? &lt;br /&gt;&lt;br /&gt;- Ecc. 3:22&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4643520153149691058?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4643520153149691058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4643520153149691058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4643520153149691058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4643520153149691058'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/another-birthday-past.html' title='Another birthday past'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2394062122134125693</id><published>2010-12-25T20:34:00.000-08:00</published><updated>2010-12-25T20:34:41.718-08:00</updated><title type='text'>Christmas Spirit</title><content type='html'>Standing in the doorway, early snowflakes&amp;nbsp;&lt;div&gt;falling gently down. A&amp;nbsp;quiet violence lights&lt;/div&gt;&lt;div&gt;the nighttime sky. Our darkness was long ago&lt;/div&gt;&lt;div&gt;stolen by the kings of business and commerce.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Their light could not illuminate, only confuse and irritate.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Meltwaters dripping slowly&amp;nbsp;from the eaves.&amp;nbsp;&lt;/div&gt;&lt;div&gt;The TV fades into the distance,&amp;nbsp;no video&amp;nbsp;&lt;/div&gt;&lt;div&gt;succubus to steal the soul of our conversation. &amp;nbsp;&lt;/div&gt;&lt;div&gt;No conversation left to be had. Just drips&lt;/div&gt;&lt;div&gt;of ice water punctuating the silence.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2394062122134125693?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2394062122134125693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2394062122134125693' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2394062122134125693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2394062122134125693'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/christmas-spirit.html' title='Christmas Spirit'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5228958410054235952</id><published>2010-12-24T07:56:00.000-08:00</published><updated>2010-12-24T13:46:38.276-08:00</updated><title type='text'>Storage without the GitHub price</title><content type='html'>So, I'm looking at GitHub and thinking, "It's a great service, but what are the other options?"&amp;nbsp;Their micro plans are a very good value at $84 (USD) to $264 per year, but I just purchased a 1 terabyte LaCie NAS for about $150, and I'm already paying about $60 per month for broadband access to my (home) office. Would self-hosting my own space make sense?&lt;br /&gt;&lt;br /&gt;The main disadvantage of&amp;nbsp;using an office-based solution, in two words, is "lightning strikes". Most office equipment is exposed to higher risks of electrical surges or direct strikes, especially when it is located in a residential building. Forget about what uninterruptible power supply companies and line filter vendors will tell you -- if lightning strikes any utility connected to your home, chances are good that their equipment will be the first, but not the last, to be taken out. Lightning can travel miles through air, so a 1/4 inch spark gap isn't going to be much protection.&lt;br /&gt;&lt;br /&gt;And computer years are logarithmic, especially the consumer-grade stuff most of us use at home offices. A&amp;nbsp;lot of equipment is just going to fail after a couple of years. At three years, odds are much better for failure. At five years, even if it is still running your equipment will appear to have been purchased eons ago and you'll wish it &lt;i&gt;would&lt;/i&gt; fail. I don't look at my LaCie NAS so much as an investment, as a necessary expense for the sake of quickly restoring my MacBook Pro. It just does not pay back to deploy mission critical services on an ad-hoc platform.&lt;br /&gt;&lt;br /&gt;Especially if it is &lt;i&gt;your&lt;/i&gt; mission, you'll put in way too much time to fix and maintain the platform. It is certainly fun to hack devices to get, eg, git running on a NAS device, but unless you are using that knowledge to build a salable infrastructure as a paid service, it makes no sense at all to pursue. It isn't your core competency and you don't gain competitive advantage by doing things in a technically curious but otherwise inferior way. &lt;br /&gt;&lt;br /&gt;Finally, vendors make it hard all the way around to deploy your own micro services. Broadband providers are well known for limiting what you can do with their bandwidth. LaCie blocked a Webdav based hack to enable ssh access (and hence a GIT install), because it was also an obvious back-door security hole.&lt;br /&gt;&lt;br /&gt;So a home-brew solution is really kind of stupid on its face. The one valid reason for doing it at all, is if your technical curiosity leads to a genuinely better way of managing your data. I can see a massively distributed peer-to-peer rsync like service being a way for micro businesses to avoid dependence on large data centers. Again, as a curiosity, perhaps, but that is a far cry from a sensible operational strategy.&lt;br /&gt;&lt;br /&gt;Interestingly, though, LaCie offers an alternative in the form of Wuala (pronounced like the French word "viola"), a service offering encrypted file storage space. Wuala is very much like DropBox, and reportedly has faster throughput. One other attractive feature is that you can trade excess storage capacity on your LaCie NAS for space for cloud space... in effect by allowing a section of your NAS to be part of the cloud itself. Not sure I want to trade my bandwidth as well, nor risk getting on the radar of the broadband provider.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5228958410054235952?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5228958410054235952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5228958410054235952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5228958410054235952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5228958410054235952'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/storage-without-github-price.html' title='Storage without the GitHub price'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5607998559701001821</id><published>2010-12-21T04:21:00.000-08:00</published><updated>2010-12-21T04:21:00.435-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Science-Technology-Engineering-Math (STEM)'/><title type='text'>URI Knot Theory</title><content type='html'>It is proposed to use language developed in the theory and practice of knots, as a primary metaphor for the architecture of the Universal Resource Identifier.  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;br /&gt;As remote as mathematicians and topologists can bring Knot theory, the practical application is immensely approachable to most people. At the very least, they understand implicitly how useful and at the same time challengingly complex it can be to arrange loops in strings of tensile material.  URIs are strings, and tie together the World Wide Web through a process which involves pulling &amp;amp;emdash; which is to say tension &amp;amp;emdash; as the primary means of establishing connectedness. That is to say, URIs are knots. &lt;br /&gt;&lt;br /&gt;The study of knots is at once both a highly developed intellectual pursuit and a supremely pragmatic, almost purely mechanical skill. The architecture of a knot determines its strength, aesthetic beauty, elegance and approachability, and ultimately whether it has any utility in practice.  The art and science of knots goes back into prehistory, and thus it evolved a language and sets of patterns that well-describe thousands of years of problem solving, where the problems involve tying things together. Thus, the language of knots should be a rich source of language well-adapted to the problems of designing URI architectures. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Background and Overview of The Language of Knots&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;From the perspective of analyzing the mechanics of a knot, it is conventionally decomposed into the following parts: &lt;br /&gt;&lt;dl&gt;&lt;dt&gt;Bight&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Bitter end&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Loop&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Elbow&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Standing end&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Standing part&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Turn&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Working end&lt;br /&gt;&lt;/dt&gt;&lt;dt&gt;Working part&lt;br /&gt;&lt;/dt&gt;&lt;/dl&gt;As a hint of the fecundity of this language, consider briefly the idea of the "Working End" of a line: it is the leading portion which allows further extension of, and adaptations to, the knot. Just as some knots can be constructed in the middle of the line, it is predicted based on the metaphor that some URIs can be constructed as fragment taken out of a continuous string, without access to the working end.&lt;br /&gt;&lt;br /&gt;At the time of the first draft of this post, August 3rd 2010, a &lt;a href="http://www.google.com/search?hl=en&amp;amp;safe=off&amp;amp;client=firefox-a&amp;amp;hs=0ua&amp;amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;amp;q=%22knots%22+%22uri+architecture%22&amp;amp;aq=f&amp;amp;aqi=&amp;amp;aql=&amp;amp;oq=&amp;amp;gs_rfai="&gt;Google search &lt;/a&gt;indicated no results on the query ' knots "uri architecture" ', and similar searches failed to produce any results. I have yet to do a formal literature search, but the Google results suggest that it is an idea which is not thoroughly discussed, and is perhaps a novel contribution. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Types of Knots&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The common practical (or alternatively, the mathematical) classification of knots can also provide a meaningful working language for URI architectures. The list is from the &lt;a href="http://en.wikipedia.org/wiki/Knot"&gt;Wikipedia entry on knots&lt;/a&gt;. Considering what each might mean in a Knot Theory of URI architectures leads to interesting possibilities for enriching the language of addressing on the Web.&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Bend_knot" title="Bend knot"&gt;Bend&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot uniting two lines (for knots joining two ends of the same line, see &lt;a href="http://en.wikipedia.org/wiki/Binding_%28knot%29" title="Binding (knot)"&gt;binding knots&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Loop_%28knot%29" title="Loop (knot)"&gt;loops&lt;/a&gt;).&lt;a href="http://en.wikipedia.org/wiki/List_of_bend_knots" title="List of bend knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Binding_%28knot%29" title="Binding (knot)"&gt;Binding&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot that restricts object(s) by making multiple winds. &lt;a href="http://en.wikipedia.org/wiki/List_of_binding_knots" title="List of binding knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Coil" title="Coil"&gt;Coil&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;Knots used to tie up lines for storage.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Decorative_knot" title="Decorative knot"&gt;Decorative knot&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A complex knot exhibiting repeating patterns often constructed around and enhancing an object.&lt;a href="http://en.wikipedia.org/wiki/List_of_decorative_knots" title="List of decorative knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Hitch_knot" title="Hitch knot"&gt;Hitch&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot tied to a post, cable, ring, or spar. &lt;a href="http://en.wikipedia.org/wiki/List_of_hitch_knots" title="List of hitch knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Lashing_knot" title="Lashing knot"&gt;Lashing&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot used to hold (usually) poles together.&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_lashing_knots" title="List of lashing knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Loop_%28knot%29" title="Loop (knot)"&gt;Loop&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot used to create a closed circle in a line. &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_loop_knots" title="List of loop knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Braid" title="Braid"&gt;Plait&lt;/a&gt; (or Braid)&lt;/dt&gt;&lt;dd&gt;A number of lines interwoven in a simple regular pattern.&lt;a class="new" href="http://en.wikipedia.org/w/index.php?title=List_of_plait_knots&amp;amp;action=edit&amp;amp;redlink=1" title="List of plait knots (page does not exist)"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Slip_knot" title="Slip knot"&gt;Slip&lt;/a&gt; (or Running)&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot tied with a hitch around one of its parts. In contrast, a  loop is closed with a bend. While a slip knot can be closed, a loop  remains the same size.&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_slip_knots" title="List of slip knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Seizing" title="Seizing"&gt;Seizing&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot used to hold two lines or two parts of the same line together.&lt;a class="new" href="http://en.wikipedia.org/w/index.php?title=List_of_seizing_knots&amp;amp;action=edit&amp;amp;redlink=1" title="List of seizing knots (page does not exist)"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Sennit" title="Sennit"&gt;Sennit&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A number of lines interwoven in a complex pattern. &lt;a class="new" href="http://en.wikipedia.org/w/index.php?title=List_of_sennit_knots&amp;amp;action=edit&amp;amp;redlink=1" title="List of sennit knots (page does not exist)"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Rope_splicing" title="Rope splicing"&gt;Splice&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot formed by interweaving strands of rope rather than whole  lines. More time-consuming but usually stronger than simple knots.&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_splices" title="List of splices"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Stopper_%28knot%29" title="Stopper (knot)"&gt;Stopper&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot tied to hold a line through a hole.&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_stopper_knots" title="List of stopper knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Trick" title="Trick"&gt;Trick&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A knot that is used as part of a magic trick, a joke, or a puzzle. &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/List_of_trick_knots" title="List of trick knots"&gt; &lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://en.wikipedia.org/wiki/Whipping_knot" title="Whipping knot"&gt;Whipping&lt;/a&gt;&amp;nbsp;&lt;/dt&gt;&lt;dd&gt;A binding knot used to prevent another line from fraying.&lt;/dd&gt;&lt;/dl&gt;I will discuss more on the applications of this language to problems of URI architectures in follow up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5607998559701001821?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5607998559701001821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5607998559701001821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5607998559701001821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5607998559701001821'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/08/uri-knot-theory.html' title='URI Knot Theory'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4394672371923061585</id><published>2010-12-12T09:19:00.000-08:00</published><updated>2010-12-18T17:33:26.018-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Social Networking'/><title type='text'>On-line Meeting Options</title><content type='html'>Recently, a member of the Raleigh-Durham Web Design Group challenged me to hold on-line meetings for the group. I'm really interested in the the physical meetings, and remain a bit skeptical that on-line &lt;i&gt;anything&lt;/i&gt; is a substitute for&amp;nbsp;face-to-face interaction. Yet there are some interesting possibilities.&lt;br /&gt;&lt;br /&gt;It makes me curious: what does "on-line" really offer us? The mundane features seem to be&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;screen sharing (with or without keyboard and mouse pointer sharing)&lt;/li&gt;&lt;li&gt;instant messaging&lt;/li&gt;&lt;li&gt;conference calling&lt;/li&gt;&lt;li&gt;videoconferencing&lt;/li&gt;&lt;li&gt;presentation or application sharing&lt;/li&gt;&lt;li&gt;session recording&lt;/li&gt;&lt;li&gt;whiteboarding&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Personally, I've never seen a high-tech conferencing option that doesn't suck compared to the&amp;nbsp;elegant simplicity of a low-tech&amp;nbsp;in-person meeting. But that's beside the point: on-line services are not a substitute for human communication. The members who are asking seem to be saying that the costs of attending in-person meetings outweighs the reward... but some of them may be willing to put out some effort to meet on-line instead.&lt;br /&gt;&lt;br /&gt;We are a volunteer group, so free or low-cost alternatives are attractive. &amp;nbsp;Members use PCs, Mac, and even Linux systems, so single-platform clients are ugly.&lt;br /&gt;&lt;br /&gt;Some of the more obvious options:&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: none;"&gt;GoToMeeting&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;Join.Me&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;DimDim&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;Yugma&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;Mikogo&lt;/li&gt;&lt;/ul&gt;Of these, Yugma's free offering stands out. It integrates with Skype, and allows up to 20 participants on-line.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;We are looking for options. What are they?&amp;nbsp;&amp;nbsp;Is there anything better for remote members than screen sharing? What's the latest and greatest in telepresence? What features are bloat and what do people actually use in practice?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4394672371923061585?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4394672371923061585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4394672371923061585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4394672371923061585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4394672371923061585'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/on-line-meeting-options.html' title='On-line Meeting Options'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2547601018281878283</id><published>2010-12-10T06:06:00.000-08:00</published><updated>2010-12-18T17:35:45.378-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pith'/><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>Social Networking and Propagation of Ignorance</title><content type='html'>People tend to think of ignorance in terms of something absent, as a gap or a hole in conceptual space. That's a pretty ignorant view of ignorance.&lt;br /&gt;&lt;br /&gt;Ignorance, by its nature, is represented in peoples brains by neural patterns, is exchanged in communication, and is clearly evident when mob-think pervades Facebook discussions. &amp;nbsp;Urban myths are ignorance encapsulated as the stories of our modern apocrypha. &lt;br /&gt;&lt;br /&gt;Ignorance, when realized consciously, can be variably hope, fear, or some other longing, but never faith, confidence, or trust. Without knowing what others don't know, ignorance is not just bliss: it pervades everything you say and do rather deeply and very materially.&lt;br /&gt;&lt;br /&gt;Fighting ignorance with ignorance is not like fighting fire with fire. It is more like burning your neighbor's house down because you see fire on the horizon. That strategy is not very likely to be successful, even if it you are taking action.&lt;br /&gt;&lt;br /&gt;This is the truest danger of social networking: ignorance is a learned meme.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2547601018281878283?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2547601018281878283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2547601018281878283' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2547601018281878283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2547601018281878283'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/social-networking-and-propagation-of.html' title='Social Networking and Propagation of Ignorance'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-611891705377616793</id><published>2010-12-08T04:25:00.000-08:00</published><updated>2010-12-08T04:25:01.232-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive Enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='Universal Design'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='Graceful Degradation'/><title type='text'>Unnatural Bifurcation of Progressive Enhancement vs Graceful Degradation</title><content type='html'>I'm working a couple of projects out of NC State University, where &lt;a href="http://www.ncsu.edu/www/ncsu/design/sod5/cud/about_ud/udprinciples.htm"&gt;Universal Design&lt;/a&gt; is not just a buzzword, it is a &lt;a href="http://www.design.ncsu.edu/cud/"&gt;whole design center&lt;/a&gt;. &amp;nbsp;We recently discussed priorities for an HTML5/RoR Web application (in a nutshell it is to be a social delivery vehicle for giving diagnostic assessment to kids), and the subject was raised.&lt;br /&gt;&lt;br /&gt;We are dealing with many different mobile devices, and the problems we are face are an extension of those &amp;nbsp;seen by designers working toward different desktop platforms and browser combinations. That brings to mind several other philosophical approaches as well, among them &lt;a href="http://www.transcendingcss.com/"&gt;Transcendent CSS&lt;/a&gt; and &lt;a href="http://developer.yahoo.com/yui/articles/gbs/"&gt;Yahoo's Graded Browser Support.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;NCSU incorporates its own design philosophies into Universal Design, so I don't want to mislead the reader, but my comments are not about any one philosophy but about a tendency among all of them to take the problem as a single dimension and premise the solution as a two-partition.&lt;br /&gt;&lt;br /&gt;More specifically, quoting the YUI Graded Browser Support article:&lt;br /&gt;&lt;blockquote&gt;Graceful degradation prioritizes&amp;nbsp;presentation, and permits less widely-used browsers to receive less (and give less to the user). Progressive enhancement puts&amp;nbsp;content&amp;nbsp;at the center, and allows most browsers to receive more (and show more to the user).&lt;/blockquote&gt;In our case, the application is perceived, navigated, and reasoned about as an application with a set of behaviors and data to be stored and retrieved. Both "presentation" and "content" are second-class citizens; the behavior of the tooling takes precedence by an order of magnitude, overshadowing all else. &amp;nbsp;Whether that is right or wrong, that is the way it is on many if not most Web application projects.&lt;br /&gt;&lt;br /&gt;My point is certainly not to argue for or against a focus on tooling; rather, that in any dynamical system it is the trajectory that is being followed that is of interest, not any one static coordinate. Content and presentation are coordinates in the space, and don't really give us the conceptual tools necessary to analyze the trajectories of moving objects.&lt;br /&gt;&lt;br /&gt;The bifurcation is unnatural, and one might suspect it is because it is being applied to applications whose meta-model doesn't really track that of the Web. They work, not because they treat their information as content or cleanly delineate content and presentation layers, but because they use model-view-controller architecture.&lt;br /&gt;&lt;br /&gt;Hence, there is a tension between understanding these applications in terms of content (and the two philosophical approaches to making designs adaptive), and understanding these applications in terms of behavior. For the most part, the applications, by design, ignore content as means of integrating behavior and strongly favor an explicit, imperative approach to sculpting a system.&lt;br /&gt;&lt;br /&gt;There is really nothing progressive about imperative coding; really it is rather old-school.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-611891705377616793?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/611891705377616793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=611891705377616793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/611891705377616793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/611891705377616793'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/unnatural-bifurcation-of-progressive.html' title='Unnatural Bifurcation of Progressive Enhancement vs Graceful Degradation'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-4170612483601880227</id><published>2010-12-06T23:00:00.000-08:00</published><updated>2010-12-06T23:00:02.444-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Hobo'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><title type='text'>Hobo: Play play play, edit edit edit, do stuff...</title><content type='html'>So, I'm about ready to do something grounded with the Hobo/Heroku/Git/RubyOnRails/Rails technology stack.&lt;br /&gt;&lt;br /&gt;One of the really sad things about the present state of Web technology, is the amount of preliminary technology stack setup that has to go on just in order to get to the starting position. That's another series of posts right there, but I digress.&lt;br /&gt;&lt;br /&gt;A cool thing about OSX is that it allows terminal sessions to be pre-configured to launch commands, then bundled into groups, so I can launch (a) a regular command window in which to run shell commands or rails consoles (b) a terminal in which to run the development server (c) a terminal in which to run Jasmine (d) a terminal in which to run rake, rspec, steak, cucumber, etcetera and (e) a MacVim with NerdTree; and have them all pre-configured with the right shell, Ruby, and Gems. &amp;nbsp; A featherweight setup for development of a specific application can be configured within a few minutes and launched with one click. But again, I digress.&lt;br /&gt;&lt;br /&gt;Start up the server for Leapercan; oops -- my other logged in user has a Rails 3 app running on port 3000 -- need to use -p option to make this one run on, Idunno, port 3030.&lt;br /&gt;&lt;br /&gt;/script/server -p 3030&lt;br /&gt;&lt;br /&gt;Huh. MySQL gives an error:&lt;br /&gt;&lt;br /&gt;Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)&lt;br /&gt;&lt;br /&gt;OK, this isn't the first time MySQL has gone AWOL under OSX. I'm still wondering why this is happening. Workaround seems to be: ps -ef|grep mysql to get the PID of the MySQL server, then kill $PID or kill -9 $PID to force the service to start a new process. Of course, MySQL has been installed to load automatically as a process upon boot, and to restart if it is ever killed. Killing the MySQL process works.&lt;br /&gt;&lt;br /&gt;Ah, but alas, now it is really late, and I've got to pause again. Perhaps the next thing I'll do is create a&amp;nbsp;questionnaire&amp;nbsp;application -- something to play out 25 questions or so in order, and capture the results in a simple table. I'll use a one-time-pad to provide some measure of scope of access, to limit the visibility of the questionnaires to just those who should be authorized to fill one out.&lt;br /&gt;&lt;br /&gt;I'll also need a time-limited list of authorizations -- basically just a mapping of user identities to scope identifiers. &amp;nbsp;Both elements of the mapping could be opaque, but the user identities should be supplied externally. The idea here is that an institutional user should be able to load up a list of authorizations for a one-time use.&lt;br /&gt;&lt;br /&gt;Another aspect of the system: the user interface should be Web based and targeted toward mobile platforms, particularly the iPhone/iPad/iPod Touch or similar Android devices. It should not give any special consideration toward working on an IE browser or any other insecure platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-4170612483601880227?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/4170612483601880227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=4170612483601880227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4170612483601880227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/4170612483601880227'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/12/hobo-play-play-play-edit-edit-edit-do.html' title='Hobo: Play play play, edit edit edit, do stuff...'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6082070755425740372</id><published>2010-11-28T12:37:00.000-08:00</published><updated>2010-11-28T12:37:30.722-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UNIX'/><category scheme='http://www.blogger.com/atom/ns#' term='OSX'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><title type='text'>Things I Don't Miss About Windows</title><content type='html'>After working on a MacBook Pro with OSX Snow Leopard for a few months, I almost go into convulsions when I am forced to tolerate the utter inferiority of Microsoft Windows.&amp;nbsp; Don't ask me which version: XP, Vista, or 7 are all just different colors of terrible.&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;While UNIX was a proven and well-understood operating system (OS) for mini computers, the original PCs were underpowered and had to settle for much less than a real OS. Yet UNIX had captured much critical knowledge about how to succeed at providing access to computer resources.&amp;nbsp; Support for multiple users, connectivity, and the security it would require were accommodated by fundamental design decisions built into its core.&lt;br /&gt;&lt;br /&gt;Over years the feature set of Microsoft's OSs have expanded to cover many of the same requirements as UNIX, yet without the same level of consistency and performance as the latter.&amp;nbsp; The Windows OS line is itself probably responsible for more security breaches and real dollar losses expended in dealing with its security issues, than any other OS on the face of the planet. &lt;br /&gt;&lt;br /&gt;Steve Jobs made a brilliant move in adopting a UNIX style core for OSX. Are there still flaws? Sure. But you just don't see the time robbing, attention wasting, excessive security risks that you are guaranteed to see under a Windows regime. &lt;br /&gt;&lt;br /&gt;They say, "Time is Money,", but really it is worse than that. You will &lt;i&gt;never&lt;/i&gt; get back the time you lose dealing with the short comings of the Microsoft platform. Best never to go that way, for down that path lies madness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6082070755425740372?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6082070755425740372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6082070755425740372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6082070755425740372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6082070755425740372'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/things-i-dont-miss-about-windows.html' title='Things I Don&apos;t Miss About Windows'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5840533834066586583</id><published>2010-11-26T05:00:00.000-08:00</published><updated>2010-11-26T05:00:04.733-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Industrial Strength Testing for Joomla Part 3</title><content type='html'>Under a test-first development practice  when you're rolling out an add-on, you should also be rolling out a  rigorous suite of tests to demonstrate that the add-on really works and  satisfies some fundamental security and accessibility criteria.&lt;br /&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;Lacking  such an automated test suite, it is not rational to expect an add-on to  perform correctly. It is certainly not reasonable to purchase an add-on  without the assurance that a test suite passes and can be repeated  under your host environment.&amp;nbsp;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;The  truth is, most software is crappy. Let's posit a valuation function Crppnss(t) to determine how crappy a piece of software is, and suppose it is inversely proportional to the number of automated tests V(t): Crppnss(t)=1/V(t). That's a reasonable assumption. Although there are studies that suggest the relationship between latent bugs and number of tests is linear, even a small number of tests can have an impact much greater than a linear correspondence. &lt;br /&gt;&lt;br /&gt;Since most Joomla  components show little or no evidence of automated testing, it follows that most Joomla components should have high Crppnss. That is to say, the theory would predict that they should be quite crappy, and that is just what we see in practice.&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;Am  I missing something here? No doubt. Yet I suspect that the Joomla/PHP  testing cup will still be less than half full when I'm filled in on what  I'm missing.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;After my initial draft of this post, I did more research. Apparently PHPUnit and Selenium, with a Joomla specific runner, is the &lt;a href="http://docs.joomla.org/Running_Automated_Tests_for_Version_1.6"&gt;soup du jour for Joomla 1.6 testing&lt;/a&gt;. It is evident that the team has put in a good amount of effort to put together a rational tool chain and process. So the Crppnss for Joomla has officially gone from infinite in version 1.5 to less than one in version 1.6.&amp;nbsp;&lt;/i&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5840533834066586583?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5840533834066586583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5840533834066586583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5840533834066586583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5840533834066586583'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/industrial-strength-testing-for-joomla_26.html' title='Industrial Strength Testing for Joomla Part 3'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8364653113359349648</id><published>2010-11-25T11:24:00.000-08:00</published><updated>2010-11-25T11:24:00.036-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Industrial Strength Testing for Joomla Part 2</title><content type='html'>&lt;div style="margin: 0px;"&gt;Following up to my previous post, I'm really regretting the lack of general testing facilities in Joomla.&amp;nbsp;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;Curiously, the Joomla MVC framework doesn't seem to help as much as hurt. Unlike Rails/Grails/Cake etc the framework doesn't do code generation and doesn't speak to clean coding idioms.&amp;nbsp;So you end up with the worst of both worlds: the constraints of a framework with the productivity of from-the-ground-up work.&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;It isn't that testing in the framework is poorly framed -- it is simply absent from the picture. &amp;nbsp;The developer shouldn't really be "rolling his own" when it comes to extending and integrating with a content management system. An active Joomla contributor could speak better to the test coverage and soundness of their PHP tool chain and technology stack, but I've seen little evidence that testing is handled with any rigor in the Joomla community at large.&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;Why do I bring it up? It costs a lot of time to fix stuff that other people broke, and I cannot afford to do that. I don't like doing it either. Foundations should be demonstrably sound and stable.&amp;nbsp; If you cannot demonstrate soundness and stability with rigorous tests, your are living in a magical pixie dust land where everything flies because you wave your hands and say it is so. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8364653113359349648?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8364653113359349648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8364653113359349648' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8364653113359349648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8364653113359349648'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/industrial-strength-testing-for-joomla_25.html' title='Industrial Strength Testing for Joomla Part 2'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8115060994161108127</id><published>2010-11-24T11:36:00.000-08:00</published><updated>2010-11-24T12:58:31.510-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Social Networking'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Let The Right One In</title><content type='html'>As I sit here in my favorite&amp;nbsp;pizzeria, &lt;a href="http://www.anziospizza.com/"&gt;Anzio's&lt;/a&gt;, having downed one too many of the tasty circular sectors, I notice someone walk in the door that I recognize. It is the owner of a local auto repair chain, and a prominent member of the local chamber.&lt;br /&gt;&lt;br /&gt;We've met a handful of times; his blank expression says that he either doesn't recognize me or doesn't want to acknowledge my presence through eye contact. Either way it is fairly strange behavior from someone in sales.&lt;br /&gt;&lt;br /&gt;Now, ordinarily I might re-re-re-introduce myself, but I've gotten some very peculiar vibes from chamber people. Like they don't know me, and don't want to. There's something very icy about meetings that they and other organizations do as networking-for-networkings-sake events.&lt;br /&gt;&lt;br /&gt;When&amp;nbsp;someone doesn't want to acknowledge you it probably isn't worth a second thought.&amp;nbsp;Like this blog entry. Ah well. No harm, no foul.&lt;br /&gt;&lt;br /&gt;The second thought is this. I contrast his behavior to that of a sales clerk. During a visit to the local Tiger Direct, uh, sorry, "CompUSA", turning to speak to my son I heard someone say, "hey, I know you". Looking back, I immediately recognized a guy who had visited the &lt;a href="http://www.meetup.com/WebDesign2-0/"&gt;Raleigh-Durham Web Design Meetup&lt;/a&gt; several months back.&lt;br /&gt;&lt;br /&gt;The guy had taken a sales clerk position after a business venture failed to come together. We chatted briefly about a common problem of finding resources to pursue projects, about networking, and his new job, then he showed my son where some cables were. &lt;br /&gt;&lt;br /&gt;What's the difference between these two people's perception of me? &amp;nbsp;One was approachable and open, and treated me as a peer; the other was absent and closed, and treated me as a total stranger. One was searching for business, the other had inherited his business from his family. One seems to have more money than the other, but I'm more likely to get leads and business from people who are open like the sales clerk than people who are closed like the auto guy.&lt;br /&gt;&lt;br /&gt;We can and do affect how people perceive us through our initial contacts with them. On the other hand, no amount of contact will alter a person's integrity. Some people are just going to play you. Others will maintain an adversarial position and keep a poker face on, no matter what your intentions, altruism, or openness. It is best not to let those ones in.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8115060994161108127?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8115060994161108127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8115060994161108127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8115060994161108127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8115060994161108127'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/let-right-one-in.html' title='Let The Right One In'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2490319282988294428</id><published>2010-11-24T10:30:00.000-08:00</published><updated>2010-11-24T10:30:00.952-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Industrial Strength Testing for Joomla Part 1</title><content type='html'>Ugh. Developing with PHP seems like such a crap shoot, and the picture gets even more muddled if you try to work with a rats nest of third-party components. In general, the quality just isn't there.&lt;br /&gt;&lt;br /&gt;My development environment for PHP bears some of the blame.&amp;nbsp;I'm not a Zend user yet, though I probably should be. Still, like C and Perl, PHP seems to encourage inelegant coding.&lt;br /&gt;&lt;br /&gt;One tool that I have used is VirtualBox. "What," say you, "does VirtualBox have to do with testing?" Well, for one thing, VirtualBox allows me to virtually reconstruct almost any hosting environment on my Lenovo T61 or MacBook Pro. The result replicates the hosting environment much better than a "WAMP" style native installer, compartmentalizes the services in a sandbox that can be put to sleep, and avoids application upgrade hell. It can even replicate the horrors of&amp;nbsp;"open_basedir=." in its PHP configuration (that breaks a LOT of packages).&lt;br /&gt;&lt;br /&gt;I've used the Joomla JumpBox appliance for a test deployment server, but recently switched to using the TurnKey Joomla appliance. Could I use shared or cloud hosting for test deployment? Yes, but the local virtual machine is private, fast, and can be junked much more quickly.&lt;br /&gt;&lt;br /&gt;When used in the development cycle, a virtual appliance is, in effect, an industrial strength test fixture.&amp;nbsp;But test fixtures are only a part of the solution to testing. A general purpose test framework is needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2490319282988294428?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2490319282988294428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2490319282988294428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2490319282988294428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2490319282988294428'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/industrial-strength-testing-for-joomla.html' title='Industrial Strength Testing for Joomla Part 1'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3886749522951284022</id><published>2010-11-22T16:41:00.000-08:00</published><updated>2010-11-28T12:01:01.956-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Hobo'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby On Rails'/><title type='text'>Hobo, Finally</title><content type='html'>During the previous setting up of the Heroku staging, I found out the name Heroku gave to my new application:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating afternoon-water-18...... done&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Created http://afternoon-water-18.heroku.com/ | git@heroku.com:afternoon-water-18.git&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Git remote leapercan added&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, that's a bit strange, but I can deal with it. The name of my app as known by Heroku is "afternoon-water-18".&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I need a database for my Hobo. I choose MySQL, just because it makes me do something to set up. Plus, I've already got it installed.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I update my Gemfile to include the mysql gem:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;mvim Gemfile&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;2G&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;A&lt;return&gt;&lt;/return&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;gem 'mysql'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;&lt;esc&gt;&lt;/esc&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;:wq&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;then invoke bundler again&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bundle install&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now to create the database:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;mysql -h localhost -u root&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;mysql&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;create database leapercan;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;Query OK, 1 row affected (0.12 sec)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;mysql&amp;gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;quit&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;Bye&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I don't have a password set up for my database. I should. There's no excuse for laziness, except procrastination. I'll do that later. &amp;nbsp;The changes will go into database.yml . Since I don't have a password set up it should just work.&lt;br /&gt;&lt;br /&gt;Now I call Hobo to generate the application:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;hobo -d mysql leapercan&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lots of output. Well, everything is great, except that the app now lives under a subdirectory. I use mv to put the files up one directory.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;mv leapercan/* .&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;rmdir leapercan&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There, that's better. Next time I'll do that a bit differently.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I follow the tutorial from here, and create a hobo migration:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;ruby script/generate hobo_migration&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;Unknown database 'leapercan_development'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Uh-oh... did I miss something obvious? Yup -- I omitted the _development from the intended database name... go back into mysql... drop database leapercan; create database leapercan_development;&lt;br /&gt;&lt;br /&gt;Try again... looks good this time. It asks me if I want to generate or migrate now, or cancel? &amp;nbsp;I migrate now and accept the default migration name. Hobo takes care of running the migration for me, so I don't have to rake db:migrate at this point.&lt;br /&gt;&lt;br /&gt;OK, so time to try it out a little:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;ruby script/server&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A mongrel server is started, which we can visit at localhost:3000. &amp;nbsp;Very niftily (I know that's not a word): hobo has created a closed shell of an application with user accounts, and is ready to set up an administrative user. &amp;nbsp;Hobo feels more like a 4GL rapid application builder than Rails alone.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;I'm adding a model now. The tutorial is talking about Contacts, but I want to think about the warranty information I had to track down this morning. &amp;nbsp;I carry around keys and coins and never really have trouble finding them because they are either in my pocket or dropped into a bowl on the nightstand. I admit, sometimes I leave them in my pocket and dig them out before throwing the clothes into the laundry.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;ruby script/generate hobo_model_resource pocket name:string content:text&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Wow, it really generates a lot of stuff. A RoR purist might say it is a bit much, but I don't know enough to be that picky. I migrate again, same method as before:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;ruby script/generate hobo_migration&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cool. Now there's a new tab for Pockets, apparently with the CRUD interfaces bootstrapped for me. I create a new Pocket, call it Leapercan, and put some application maintenance details in it. Stuff someone would eventually ask about, if they were asked to support the application.&lt;br /&gt;&lt;br /&gt;It just works. That's a very, very nice quality.&lt;br /&gt;&lt;br /&gt;Did I mention how little I value debugging? Debugging other peoples' code is like trying to understand and have a discussion with another developer by relaying the messages through a stupid, more or less insane, and completely soulless being. I'm in awe of people who can do it, but I'm finding I have less and less tolerance for stuff that doesn't work as expected.&lt;br /&gt;&lt;br /&gt;The tutorial mentions how Hobo works at this point, automagically adding or removing fields and tables, based directly upon what it finds or doesn't in the models. To delete a table, just delete its model and generate another migration. You'll be doing the hobo_migration dance a lot during early development.&lt;br /&gt;&lt;br /&gt;On the other hand, rolling back to a previous version apparently involves editing of the migration files directly and a &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;rake db:migrate VERSION = version_no &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It isn't much, but I'll push it anyway. Nope... Heroku says I need to run bundler. Bundler says I don't. What gives? &amp;nbsp;It tells me to look at&amp;nbsp;http://docs.heroku.com/bundler... completely unhelpful advice... GoogleTime... looks like a common problem, but the advice offered doesn't work. Like, AT ALL.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;git add Gemfile.lock&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;git commit -m "Added Gemfile.lock"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After several attempts at modifying the Gemfile, running bundler, and adding both the Gemfile and Gemfile.lock, &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;git push leapercan master&lt;/span&gt; still craps out with that same error. Every Time. Even when I destroy and reinit the git repository.&lt;br /&gt;&lt;br /&gt;Looks like Heroku is in the crapper at this point in time. It took me from a nearly seamless experience to an brick wall. Epic fail. Waiting, wondering, and - the thing I hate most of all - debugging someone else's code.&lt;br /&gt;&lt;br /&gt;I'm starting to hate you, Heroku, and I hardly even know you.&lt;br /&gt;&lt;br /&gt;So I start hacking, wildly guessing. I figure, something is lying to me, so I decide to do exactly the opposite of what it seems to be telling me. It says&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; You have modified your Gemfile in development but did not check the resulting snapshot (Gemfile.lock) into version control&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; You have deleted from the Gemfile:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; * version: 1.0.6&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;MISDIRECTION! I really wish that some programmers would learn to communicate better than brain damaged slugs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Google had a lot of bad advice, utter nonsense, akin to cutting off a chicken's head and sprinkling its blood on the ground. The true reason for the problem is that Bundler records its version number in the METADATA section (which happens to be at version 1.0.6), and the bundler up on Heroku (version 1.0.3) apparently cannot deal with the fact that it has a slightly different revision level. &amp;nbsp;So I deleted the version number line from Gemfile.lock, and BAM, it just works.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;WOOHOO!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;Except... it didn't work. The command line says "yes" but the Web interface says something went drastically wrong. Wait. I forgot one more step: the Heroku database migration.&lt;br /&gt;&lt;br /&gt;heroku rake db:migrate&lt;br /&gt;&lt;br /&gt;Ah, such sweet release. All done.&lt;br /&gt;&lt;br /&gt;The bundler version discrepancy reminds me of US EPA emissions requirements for commuter vehicles: not only do the requirements add to the cost and complexity of the auto, the emissions parts are directly the cause of most of the failures. How much difference is there between 1.0.3 and 1.0.6? Probably very little. Yet the version labels &lt;i&gt;themselves&lt;/i&gt; completely HOSED the system. There's a lesson in there somewhere, about not enforcing something that doesn't really matter.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;References&lt;/div&gt;&lt;div&gt;Rapid Rails with Hobo (Free from the Hobo site)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3886749522951284022?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3886749522951284022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3886749522951284022' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3886749522951284022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3886749522951284022'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/hobo-finally.html' title='Hobo, Finally'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-5160047818071386348</id><published>2010-11-21T15:10:00.000-08:00</published><updated>2010-11-21T15:10:00.157-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Hobo'/><category scheme='http://www.blogger.com/atom/ns#' term='Rails'/><title type='text'>Hobo on Heroku</title><content type='html'>Ok, so I'm toying with a Web application, code named "leapercan" because Leprechaun is not only unavailable as a domain name it is also difficult to spell.&lt;br /&gt;&lt;br /&gt;Not that I claim to be especially proficient in Ruby or Rails, but I've been fortunate to help a really crack team of Ruby on Rails programmers for the past couple of months. I'm a dinosaur by comparison, but I'm picking up something along the way.&lt;br /&gt;&lt;br /&gt;So I want to try something new, but RubyOnRails based. We've been using Rails 3 with all sorts of gems including RSpec, Steak, and Jasmine, and deploying with Capistrano. I'm looking for a solo app --&amp;nbsp;Hobo sounds interesting, and a free account on Heroku is an easy way to get started.&lt;br /&gt;&lt;br /&gt;Here's what I've done and found so far.&lt;br /&gt;&lt;br /&gt;Before anything else, note that I'm hanging back on versions so as to avoid having to deal with bugs at the bleeding-edge. My goal is to explore Hobo and Rails capabilities, not to debug them. &lt;br /&gt;&lt;br /&gt;Debugging time is time mostly wasted. &amp;nbsp;Like an argument with your spouse once you've worked around the disagreement you generally forget why it was a problem in the first place.&lt;br /&gt;&lt;br /&gt;First, I use RVM to manage my Ruby versions, but not the gemsets feature. So I install version 1.8.7 and set a .rvmrc up so that my work environment will default to rvm's global gemset for 1.8.7.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd ~/workspace&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mkdir leapercan&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;echo "rvm use 1.8.7@global" &amp;gt; leapercan/.rvmrc&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd leapercan&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;RVM now tells me that 1.8.7 is selected. Now, if I had other 1.8.7 apps on this machine, I might use a named gemset instead, to avoid polluting the global space; in that case, I would have used the gemset name instead of "global". Now that I think of it, that probably would have been a better idea...&lt;br /&gt;&lt;br /&gt;I confirm it is using the right Ruby. As it happens, my system ruby is also 1.8.7, so I could have avoided the download. I check the version&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;which ruby&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;/Users/mamiano/.rvm/rubies/ruby-1.8.7-p302/bin/ruby&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next, I install the bundler, because it is just easier to list the right gems in a file than to 'member the nitty-gritty details in stream-of-consciousness mode.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;gem install bundler&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After that, I use my trusty MVIM to edit the Gemfile, and put in the gems we're expecting to use:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;source 'http://rubygems.org'&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;gem 'rails', '2.3.10'&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;gem 'hobo', '1.0.2'&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;gem 'heroku', '1.13.7'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm a freakin' idiot savant, to have come up with the version numbers, right? Wrong. I used the fact that rubygems.org provides a RESTful interface to look at the all kinds of information about a given gem, and just plugged and chugged until I figured out which versions I could probably use without too much more trouble. &amp;nbsp;The format I used was&amp;nbsp;http://rubygems.org/gems/GEMNAME , where GEMNAME was one of rails, hobo, and heroku. &lt;br /&gt;&lt;br /&gt;Write and quit the Gemfile, and run bundler:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bundle install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Gahk! It complains about&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Could not find gem 'rails2.3.10 (&amp;gt;= 0, runtime)' in any of the gem sources listed in your Gemfile.&lt;/i&gt;&lt;br /&gt;&lt;div&gt;Well, that's not right. I had omitted a comma after the gem name and version number, and bundler just concatenated the two into one string. &amp;nbsp;I correct the mistake and continue.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;After a while of downloading and installing, you'll end up with a bunch of new gems in your rvm maintained gemset. You can list these with gem:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;gem list&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;*** LOCAL GEMS ***&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;actionmailer (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;actionpack (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;activerecord (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;activeresource (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;activesupport (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;bundler (1.0.6)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;configuration (1.1.0)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;heroku (1.13.7)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;hobo (1.0.2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;hobofields (1.0.2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;hobosupport (1.0.2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;json_pure (1.4.6)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;launchy (0.3.7)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;mime-types (1.16)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;rack (1.1.0)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;rails (2.3.10)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;rake (0.8.7)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;rest-client (1.6.1)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;will_paginate (2.3.15)&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;OK. So, by now I've also set up a free account on Heroku, gotten a link to activate the account, and logged in. Heroku says I need to add my public SSH key, so I do:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;heroku keys:add&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enter your Heroku credentials.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Email: &lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;mamiano@nc.rr.com&lt;/span&gt;&lt;br /&gt;&lt;b&gt;Password: &lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;********&lt;/span&gt;&lt;br /&gt;&lt;b&gt;Uploading ssh public key /Users/mamiano/.ssh/id_rsa.pub&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;(Note that I had used earlier used ssh-keygen to create my public and private keys as part of a GitHub account setup. You don't need a GitHub account to use Heroku, just git. Google it if you don't know how.)&lt;br /&gt;&lt;br /&gt;You can use "heroku help" to list a quick reference to the commands. I won't repeat them here.&lt;br /&gt;&lt;br /&gt;Heroku says I need to set up my working directory as a GIT repository, so I do:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git init&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git add .&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git commit -m "LeaperCan: gold at the end of the rainbow"&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;4 files changed, 63 insertions(+), 0 deletions(-)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;create mode 100644 .bundle/config&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;create mode 100644 .rvmrc&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;create mode 100644 Gemfile&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;create mode 100644 Gemfile.lock&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we need to tell Heroku about the new application. A helpful blogger has already run into the problem of using a slightly newer version of Rails than is standard on Heroku, and pointed out the command line to use the "bamboo" stack instead, which has my version of Rails on it:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;heroku create --stack bamboo-ree-1.8.7 --remote leapercan&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Git remote leapercan added&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, at this point, I've gotten myself a live sandbox to play in... I'm ready to actually play with a Hobo application.&lt;br /&gt;&lt;br /&gt;To Do: Play play play, edit edit edit, do stuff...&lt;br /&gt;&lt;br /&gt;Now suppose we have played enough that we have something to deploy. According to Kiwiluv, it is as simple as doing two steps:&lt;br /&gt;&lt;br /&gt;&lt;div class="p1"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git push leapercan master&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;And&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="p1" style="color: #333233; font: normal normal normal 12px/normal Courier; line-height: 18px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div class="p1" style="color: #333233; font: normal normal normal 12px/normal Courier; line-height: 18px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;heroku rake db:migrate --app heroku-app-name&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately at the moment my family wants attention and I'm just about out of play time.&lt;br /&gt;Sigh. Rather than forget what I've just done, I take what time I have left and dump it into my blog, along with the references.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;References&lt;br /&gt;&lt;a href="http://rubygems.org/gems/heroku/versions/"&gt;http://rubygems.org/gems/heroku/versions/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://rubygems.org/gems/hobo/versions/"&gt;http://rubygems.org/gems/hobo/versions/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://rubygems.org/gems/rails/versions/"&gt;http://rubygems.org/gems/rails/versions/&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://docs.heroku.com/rails"&gt;http://docs.heroku.com/rails&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.kiwiluv.com/techblog/?p=560"&gt;http://www.kiwiluv.com/techblog/?p=560&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cookbook.hobocentral.net/manual/download"&gt;http://cookbook.hobocentral.net/manual/download&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-5160047818071386348?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/5160047818071386348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=5160047818071386348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5160047818071386348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/5160047818071386348'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/hobo-on-heroku.html' title='Hobo on Heroku'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2509895062413000171</id><published>2010-11-20T16:58:00.000-08:00</published><updated>2010-11-20T16:58:00.112-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Design'/><title type='text'>A Smattering of Design Guidelines</title><content type='html'>&lt;div&gt;Use the metaphor of resources to determine consistent, implementable URL and URI patterns for your pages. Sketch your site's map. But only just sketch. &amp;nbsp;If you don't understand how this relates to your design, consider that "pages" is just a metaphor itself and the branches of site map don't necessarily mean "page".&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lay out for substantive content first.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Get specifications for the devices you expect to support for access to your information. &amp;nbsp;Generalize the specifications into a set of parameters characterizing a category of media, rather than device. &amp;nbsp;Create a style profile for each generalized category of media space. You might have a Desktop space, a high-definition smartphone space, a low-definition mobile space, a tablet space, etc. &amp;nbsp;Consider each profile a proxy for one of your audiences.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Define your profiles incrementally. Choose a grid or columnar layout, and flow content into place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Apply a strategy using  Occam's Razor to your code:&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;pluralitas non est ponenda sine necessitate&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;Which is to say, don't use more markup than absolutely necessary to convey the meaning of the message. Use CSS for style. Don't use DIVs for positioning or include other gratuitous markup&amp;nbsp;for layout tricks. &amp;nbsp;Don't rely upon the relative positions and parent/child relationships in the markup for style or layout effects beyond in-line layout.&lt;br /&gt;&lt;br /&gt;Include a browser reset. That will eliminate browser-introduced pluralities. It is regrettable that as of the year 2010 CSS3 and HTML5 still make it difficult to follow the Occam's Razor principle. But even a critic can see the situation is improving. &lt;br /&gt;&lt;br /&gt;Use Behavior Driven Development with scenarios to storyboard the site. Why is anyone looking? What do they need to do?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2509895062413000171?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2509895062413000171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2509895062413000171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2509895062413000171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2509895062413000171'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/smattering-of-design-guidelines.html' title='A Smattering of Design Guidelines'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-6248334975934592351</id><published>2010-11-19T15:44:00.000-08:00</published><updated>2010-12-18T17:59:30.025-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Joomla means carnage</title><content type='html'>Man oh man. I just got done futzing around with an XML RPC service plugin for Joomla. What a nightmare, like slogging up to your neck in feces for four hours.&lt;br /&gt;&lt;br /&gt;Thing is, it isn't that complicated a problem, but trying to do things the "right" way is what makes it virtually impossible to accomplish.&lt;br /&gt;&lt;br /&gt;First, there is little published information that is in any way self-consistent. Please don't tell me about the so-called "Master ..." book for Joomla. It is spotty at best. The information might be there, but it is so poorly organized that you have to jump around in the book to patch it together, making it that much more difficult to judge if you've gotten the pieces right. &amp;nbsp;Still, one can muddle through part of the way on that.&lt;br /&gt;&lt;br /&gt;Second, how do you test it? &amp;nbsp;There is no admin side functionality for testing the RPC interfaces you enable. Isn't it a little bit mission critical to know if they work? &lt;br /&gt;&lt;br /&gt;Third, none of the Joomla APIs appear to be very stable. Write something custom for it, and you're most &amp;nbsp;certainly guaranteed that custom code will break when you update. At least, you'll have to test it thoroughly before updating any production system that uses your code.&lt;br /&gt;&lt;br /&gt;Fourth, debugging this stuff is one epic hack after another, just for the debug environment. I tried the PHP XMLRPC debugger and finally had to give up after being roadblocked in three completely different ways.&lt;br /&gt;&lt;br /&gt;First, the xmlrpc feature had been left out of the "hardened" php test server.&lt;br /&gt;&lt;br /&gt;Then the Javascript based debugger started firing off "OPTION" requests because the test server was running on the local network (The standards working group that came up with the rule of sending an OPTIONS header aught to be taken out back and stoned for that particular hack. At least, the browser should warn you it is deliberately ignoring the method of your request and pretending to be brain-dead.)&lt;br /&gt;&lt;br /&gt;Then, when things didn't work, the debugger doesn't give you details, it just says "Didn't receive 200 OK from remote server. (send failed)". OK, um, DUH. What failed? &lt;br /&gt;&lt;br /&gt;Well, best not to continue. Down that path lies madness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-6248334975934592351?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/6248334975934592351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=6248334975934592351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6248334975934592351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/6248334975934592351'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/joomla-means-carnage.html' title='Joomla means carnage'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3904102004026524814</id><published>2010-11-19T13:26:00.000-08:00</published><updated>2010-11-19T13:26:00.439-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Criticism'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Request for Proposal, or, Trying to Bypass Design</title><content type='html'>Consider what an RFP for a house might look like, were it to be written in the manner of an RFP for a Web site or software project:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Request For Proposal&lt;br /&gt;&lt;br /&gt;Requirements&lt;br /&gt;1) Contractor shall construct one building shelter, to accommodate one (1) family including all bedrooms, a kitchen, dining room, and toilet(s). &lt;br /&gt;&lt;br /&gt;2) All work performed must comply with industry standards.&lt;br /&gt;&lt;br /&gt;3) Wood studs and gypsum drywall are acceptable materials for construction. &lt;br /&gt;&lt;br /&gt;Proposals without detailed plans and estimates will not be accepted.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Do you think developers give you wildly varying proposals? Is your RFP process designed to get others to do design work for you for free? Then it masks your own lack of due diligence, and you will get every bit of design that you pay for. &lt;br /&gt;&lt;br /&gt;Big Design Up Front is not necessary nor is it sufficient for a project's success. But you still need to take the process seriously. Such requests are a clear indication that the RFP writer is not at all serious about project success.&lt;br /&gt;&lt;br /&gt;Personally, I think RFPs used to elicit design input without payment are unethical. The behavior is no better than asking one dentist to lay out a strategy for fixing your teeth, then paying another to follow the program without remuneration to the first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3904102004026524814?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3904102004026524814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3904102004026524814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3904102004026524814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3904102004026524814'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/request-for-proposal-or-trying-to.html' title='Request for Proposal, or, Trying to Bypass Design'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-3894392472448431664</id><published>2010-11-18T17:45:00.000-08:00</published><updated>2010-11-18T17:45:00.696-08:00</updated><title type='text'>A Design Guideline</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Use the metaphor of resources to determine consistent, implementable URL and URI patterns for your pages. Sketch your site's map. But only just sketch. &amp;nbsp;If you don't understand how this relates to your design, consider that "pages" is just a metaphor itself and the branches of site map don't necessarily mean "page".&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lay out for substantive content first.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Get specifications for the devices you expect to support for access to your information. &amp;nbsp;Generalize the specifications into a set of parameters characterizing a category of media, rather than device. &amp;nbsp;Create a style profile for each generalized category of media space. You might have a Desktop space, a high-definition smartphone space, a low-definition mobile space, a tablet space, etc. &amp;nbsp;Consider each profile a proxy for one of your audiences.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Define your profiles incrementally. Choose a grid or columnar layout, and flow content into place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Follow Occam's Razor:&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;pluralitas non est ponenda sine necessitate&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;Which is to say, don't use more markup than absolutely necessary to convey the meaning of the message. Use CSS for style. Don't use DIVs for positioning or include other gratuitous markup&amp;nbsp;for layout tricks. &amp;nbsp;Don't rely upon the relative positions and parent/child relationships in the markup for style or layout effects beyond in-line layout.&lt;br /&gt;&lt;br /&gt;Include a browser reset. That will eliminate browser-introduced pluralities. The Yahoo! UI library has one. Eric Meyer has another. There are plenty of examples.&lt;br /&gt;&lt;br /&gt;Choose a dominant typeface family and style to fit the message, audience, medium, and purpose. &amp;nbsp;Use a san-serif font for body text, a serif font for headings. Align the sizing of both, since characters in two fonts will often differ in size. Use a font stack to specify the desired font, one or more fallback fonts, and a generic family as a stand-in. Carefully consider use of an OT/TTF or SVG Webfont with or without a foundry service like Typekit or Typotheque, or WOFF.&lt;br /&gt;&lt;br /&gt;Choose a subordinate typeface for UI controls. Distinguish them with different colors or a different font family.&lt;br /&gt;&lt;br /&gt;Determine word spacing, letter spacing, line spacing,&lt;br /&gt;&lt;br /&gt;Use Em for relative sizes, but understand that one Em is equal to 100% of the font size property in effect within the context of the markup. So there is a cumulative effect of the settings.&lt;br /&gt;&lt;br /&gt;Use proper glyphs for hyphen, en-dash, em-dash, and minus signs (I don't on my blog). Use the HTML entities for these and other special characters. &amp;nbsp;(See smartypants or typogrify.)&lt;br /&gt;&lt;br /&gt;For text blocks and columns, use multiples of ems to set line width relative to multiples of characters. Aim for 10-15 words or 75-100 characters per line. Set line height with a unitless number so that it is based on the font size.&lt;br /&gt;&lt;br /&gt;CSS3 may support hanging punctuation (quotes and parenthesis are hung in the margins.)&lt;br /&gt;&lt;br /&gt;Check out webtypography.net, usabletype.org, alistapart.com/topics/design/typeography&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-3894392472448431664?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/3894392472448431664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=3894392472448431664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3894392472448431664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/3894392472448431664'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/design-guideline.html' title='A Design Guideline'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8794510156617034623</id><published>2010-11-17T08:00:00.000-08:00</published><updated>2010-11-17T15:10:39.000-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Design'/><title type='text'>Points vs Pixels vs Percents vs Ems</title><content type='html'>There's a saying attributed to Mark Twain that one should never argue with a fool because onlookers may not be able to tell the difference. I've seen a lot of Web people arguing about&amp;nbsp;accessibility, design, and typographic units, and I am forced to agree with Clemens. &lt;br /&gt;&lt;br /&gt;I'd like to see some compelling arguments. There are none. Units are units, and whether the browsers actually do the right thing or not is quite irrelevant to the question of accessibility. &lt;i&gt;A site cannot be made accessible by hacking it to coincidentally work around defects in specific browsers.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;Accessibility to a building is not a property of the bricks and mortar that make it up, but an emergent condition stemming from the challenges a person faces when navigating the patterns present in the structure. We cannot design buildings to address every challenge, so instead we create building standards to guide the minimum architectural feature set.&lt;br /&gt;&lt;br /&gt;Similarly, accessibility of a Web site is not a property of the bits, nor is it feasible to design them to address every challenge faced by users - instead we have nascent standards for building-in accessibility by proxy, as a set of architectural features.&lt;br /&gt;&lt;br /&gt;When we build our town halls and commercial buildings to ADA standards, what we are saying is that we expect certain patterns and relationships to be exhibited in the resulting structure. What we are not saying is that the door frames were field modified to accommodate an Acme brand Model 68020 wheelchair. &amp;nbsp;Nor are we saying that the door frames were field modified because the doors were found to be constructed of defective alloys. The first case is too specific to one assistive device, and second case is clearly cause to demand a completely new set of standards-compliant doors.&lt;br /&gt;&lt;br /&gt;Changing style sheets and muddling with markup in order to make something "accessible" for a specific set of browsers is ludicrous. It also smacks of being way too touchy-feely, relying upon subjective qualitative ideation rather than quantitative assessment. &lt;br /&gt;&lt;br /&gt;Either we develop to standards, or we don't. Hand waving about pixels being inaccessible, points being "just for print," or percentages and ems being superior, is missing that argument entirely. &amp;nbsp;If some feature of the site doesn't work for you, to the extend it is specific to a given browser it is not an issue of accessibility but a defect in the product... and we will all be better served if we stop making accommodations to defective products.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8794510156617034623?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8794510156617034623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8794510156617034623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8794510156617034623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8794510156617034623'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/points-vs-pixels-vs-percents-vs-ems.html' title='Points vs Pixels vs Percents vs Ems'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-1769226377412993361</id><published>2010-11-16T16:56:00.000-08:00</published><updated>2010-11-16T16:56:00.114-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>I'm Enjoying Ruby on Rails and BDD</title><content type='html'>Nothing beats writing tests first with a truly integrated framework like Rails. &amp;nbsp;Steak and Jasmine make it practical, even if they have their oddities. FactoryGirl, I'm not so sure about, but once it is set up it seems to be pretty reliable.&lt;br /&gt;&lt;br /&gt;Done correctly, things just work. Done incorrectly, especially with FactoryGirl, side-effects can really clobber you and steal precious development hours away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-1769226377412993361?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/1769226377412993361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=1769226377412993361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1769226377412993361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/1769226377412993361'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/im-enjoying-ruby-on-rails-and-bdd.html' title='I&apos;m Enjoying Ruby on Rails and BDD'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-2540096158186692283</id><published>2010-11-16T08:00:00.000-08:00</published><updated>2010-11-16T13:52:22.144-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Design'/><title type='text'>The case for concrete sizing</title><content type='html'>&lt;span class="Apple-style-span" style="color: #222222; font-family: Verdana,Arial,sans-serif; font-size: 12px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: Verdana,Arial,sans-serif; font-size: 12px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: Verdana,Arial,sans-serif; font-size: 12px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: Verdana,Arial,sans-serif; font-size: 12px;"&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;What people have to say about "points" in Web typography. Points...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;are a "standard method" for print typography&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;may be more legible in print, less legible on screen&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;and page resizing may not work consistently in certain browsers&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;are not relative to changes in base font-size (smallest, smaller, ... larger, largest)&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;OK, so I'm seeing the real problem here: lots and lots of Web designers are mixing the metaphors of Web layout as a formatting process and Web layout as an interface specification.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;Don't do that.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;If you are going to design liquid layouts with relative sizes, by all means, go ahead and play. Your designs are going to be beautiful, but then again no design on the Web belongs to the author. A design is always the merging of the intentions of the author with the choices of the user, within the limitations of a browser. So all that pains-taking is going to look great, but we know that by design it is guaranteed to break.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;The thing is, points mean something objectively. In modern typography they have been defined to mean 1/72 of an inch. Yes, that's an English measure, the only widely used measurement system based upon human factors. Like our calendar it is entirely based upon the pragmatic considerations western civilization determined centuries ago. It&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&amp;nbsp;is flawed and odd, but it is objective and well grounded in our experience.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;So, tell me again, why do we want to measure fonts in pixels or percents, when we want our designs to be accessible to humans?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;Incidentally, the argument against points on the basis that Web typography must deal with multiple device formats and layouts, is fundamentally flawed. The world of print typography has far more media formats than Web browsing devices can shake a stick at, ranging from huge to tiny, and on many different types of substrates. Points work precisely because they are an objective measure that can be directly multiplied by a unitless ratio for scaling, and thus do not need to be re-interpreted for each formatting context.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-2540096158186692283?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/2540096158186692283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=2540096158186692283' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2540096158186692283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/2540096158186692283'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/case-for-concrete-sizing.html' title='The case for concrete sizing'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-7792810679565905138</id><published>2010-11-14T04:26:00.000-08:00</published><updated>2010-11-14T13:05:13.721-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Human Condition'/><title type='text'>On the ideal of networking</title><content type='html'>Thinking about some of the finer points of the &lt;a href="http://www.indieconf.com/"&gt;IndieConf&lt;/a&gt;, on the ideal strategy of choosing several people and being helpful over time with the goal of establishing numerous positive interactions, thus building trust and establishing relationships.&lt;br /&gt;&lt;br /&gt;Don't assume that payback from that strategy is uniformly distributed. It is most definitely not.&lt;br /&gt;&lt;br /&gt;It isn't random either.&lt;br /&gt;&lt;br /&gt;Nor is the payback going to be from the people that seem to be the most friendly, or those for whom you've put yourself out for the most.&amp;nbsp; At least, not at the start. &lt;br /&gt;&lt;br /&gt;What you'll find is that most people are leeches, willing to get but not to give back. Many more will undervalue anything offer that doesn't have a price attached to it. And a great number will just simply be prejudiced against something about you that has nothing to do with anything, but will prevent them from ever doing business with you. &lt;br /&gt;&lt;br /&gt;There were some key things in this respect from the IndieConf speakers on the subject:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Intentional Pursuit. They chose who to pursue, and those they chose to pursue are people around the industry in which they wish to work. &lt;/li&gt;&lt;li&gt;Quick Selectivity. They made snap judgments to quickly eliminate disfavored prospects from their list.&lt;/li&gt;&lt;li&gt;Overt Spying. They made lists, and profiled the people they were pursuing.&lt;/li&gt;&lt;li&gt;Low Commitment. They did not over-invest their time, their reputations, or their other resources.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;An example of #4 is that most of them mentioned, as the "positive interaction", sending an email note with an article of potential interest to their target, once every 45 days or so. They would review a list of their prospects once or twice a week, and with them in mind glean articles from RSS feeds and the "help a reporter"&amp;nbsp; site. If they found something they'd push out a note. Very cheap, low outlay of time and no commitment, but it reminds the prospect that you are there. &lt;br /&gt;&lt;br /&gt;Yet, people will still forget you, ignore you, or even get annoyed at you. If someone doesn't respond positively, don't obsess or fret... just move on. When you find someone who welcomes advice but never reciprocates or who actively works against you, strike them from the list and pick someone new to network with.&lt;br /&gt;&lt;br /&gt;I've spent a lot of time pursuing connections at our local chamber, and in town, with the hope of getting business. Now I see that I've done several things wrong.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;none of the chamber or town hall people are in fields in which I'd like to work, or express similar interests &lt;/li&gt;&lt;li&gt;my openness, tolerance, and patience have been extreme; in particular I was too slow to weed out poor connections&lt;/li&gt;&lt;li&gt; no tabs were kept on people, or other personal profiles, though I did stay in touch, and&lt;/li&gt;&lt;li&gt;the commitment of my time and emotional energy in volunteering, offering advice, and making other resources available, was substantial and interfered with me earning my keep elsewhere&lt;/li&gt;&lt;/ul&gt;There were people I admire, people I connect with, but I've been passed over twice for major business that I asked for, and on the whole it has become an un-enjoyable experience. Time to move on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-7792810679565905138?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/7792810679565905138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=7792810679565905138' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7792810679565905138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/7792810679565905138'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/on-ideal-of-networking.html' title='On the ideal of networking'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1095111220804824515.post-8678788744724450889</id><published>2010-11-14T04:12:00.000-08:00</published><updated>2010-12-22T07:54:52.167-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Stupid Blogger!!!!</title><content type='html'>I hate Web based applications. Always, I get fooled into spending time writing something, only to have some random keystroke navigate away from the page and into oblivion.&lt;br /&gt;&lt;br /&gt;AAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!&lt;br /&gt;&lt;br /&gt;We need to put a stop to this crap. We use these freaking interfaces&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;ALL&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;DAY&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;LONG&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;Why should they continue to be riddled with sucky design features. BACKSPACE causes you to lose all your writing? REALLY??????&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;cough&gt;&lt;clear-throat&gt;&lt;/clear-throat&gt;&lt;/cough&gt;&lt;br /&gt;&lt;br /&gt;OK, so, score one for Blogger. It saved the edit as a draft. (Insert begrudging Calvin-and-Hobbes grimace here.) It is still stupid to have backspace change the page.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1095111220804824515-8678788744724450889?l=www.unityisplural.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.unityisplural.com/feeds/8678788744724450889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1095111220804824515&amp;postID=8678788744724450889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8678788744724450889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1095111220804824515/posts/default/8678788744724450889'/><link rel='alternate' type='text/html' href='http://www.unityisplural.com/2010/11/wrq-blogger.html' title='Stupid Blogger!!!!'/><author><name>Jersey Boy</name><uri>http://www.blogger.com/profile/12949567761516669628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://1.bp.blogspot.com/_fzEHlKG_1HY/SjJYympeECI/AAAAAAAAAEY/8sxANf3fXK0/S220/PICT0011b.JPG'/></author><thr:total>0</thr:total></entry></feed>
