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

<channel>
	<title>Marked As Pertinent</title>
	<atom:link href="http://bjclark.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://bjclark.me</link>
	<description>rails, design, art, business by BJ Clark</description>
	<lastBuildDate>Mon, 23 Jan 2012 23:04:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Working Software</title>
		<link>http://bjclark.me/2012/01/working-software/</link>
		<comments>http://bjclark.me/2012/01/working-software/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 23:00:21 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=252</guid>
		<description><![CDATA[I&#8217;ve been thinking about what the minimum requirement for a programmer is. It&#8217;s an interesting topic. No one talks about it, really. What&#8217;s the most basic skill a programmer must possess to call themselves a &#8220;professional programmer&#8221;? I&#8217;d like to think that we could look at some other professions and see how they define it. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking about what the minimum requirement for a programmer is. It&#8217;s an interesting topic. No one talks about it, really. What&#8217;s the most basic skill a programmer must possess to call themselves a &#8220;professional programmer&#8221;?</p>
<p>I&#8217;d like to think that we could look at some other professions and see how they define it. Doctor&#8217;s have the saying &#8220;do no harm&#8221;, pretty good. Architects, I&#8217;d guess, have to be able to design a building that doesn&#8217;t implode. Plumbers have to build a system of pipes that doesn&#8217;t get backed up and doesn&#8217;t leak. Lawyers, at the most basic level, just need to know the laws. They just need to be correct.</p>
<p>If you try to fix your sink, and it starts spraying water all over your kitchen, you might proclaim &#8220;I&#8217;m no plumber!&#8221;. If you gave medical advice to someone, and they got sick, you&#8217;d say &#8220;I&#8217;m no doctor!&#8221;. Almost all statements prefaced with IANAL are wrong, because that person doesn&#8217;t actually know what the laws say.</p>
<p>I think we could sum this up by saying, the basis of most professions is the ability to not break anything, or be incorrect in what you say.</p>
<p>So, what can we say about programming? How do you define what makes someone a professional? Correctness? All software that I&#8217;ve ever used has been incorrect in one way or another, so we&#8217;re going to have to throw that one out. Let&#8217;s get even more basic. </p>
<p>The minimum attribute of being a profession programmer is that you deliver working programs. Your code works. It does not break. It does not make things worse.</p>
<p>How many programmers do you know that can say that?</p>
<p>I would like to hear more folks would talking about &#8220;this&#8221;. Software that works. The process of delivering software that doesn&#8217;t break, consistently. </p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2012/01/working-software/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Expanding on the Law of Demeter</title>
		<link>http://bjclark.me/2011/07/law-of-demeter/</link>
		<comments>http://bjclark.me/2011/07/law-of-demeter/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 22:28:51 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[BDD]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[active_record]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[behaviour]]></category>
		<category><![CDATA[demeter]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=235</guid>
		<description><![CDATA[Recently, my friend Avdi Grim posted a great explanation of the Law of Demeter (LoD). It&#8217;s been tweeted and posted all over the web, so hopefully you saw it and read it. I&#8217;m totally in agreement with his conclusions in that post, and LoD is a code smell I see in every MVC project I [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, my friend <a href="http://avdi.org/devblog/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+VirtuousCode+%28Virtuous+Code%29">Avdi Grim posted a great explanation of the Law of Demeter</a> (LoD). It&#8217;s been tweeted and posted all over the web, so hopefully you saw it and read it. I&#8217;m totally in agreement with his conclusions in that post, and LoD is a code smell I see in every MVC project I have ever worked in.</p>
<p>I&#8217;m going to pick on Avdi&#8217;s post just a little, but this is more-so criticism of every LoD explanation I&#8217;ve ever read. I think all of these explanations of LoD are actually quite contrite and not addressing the real problem. Avdi (and others) seem to focus on &#8220;Structrual Coupling&#8221; or exposing the &#8220;internal&#8221; (actually external*) structure of your objects to other objects that don&#8217;t need to know it.</p>
<p>An Example:</p>
<pre><code class="ruby">def user_info(user) "Name: #{user.name}. Boss: #{user.department.try(:head).try(:name)}" end</code></pre>
<p>Avdi does a beautiful job illustrating why this code is a problem but I want to go a little deeper.</p>
<p>The more insidious LoD violation see in codebases is what I&#8217;d call &#8220;behavioral&#8221; LoD violations, or, when the behavior of a class relies on the behavior of objects that are distant in the object graph.</p>
<p>My example needs a little setup. Lets say you have Vehicles which has_many <a href="http://en.wikipedia.org/wiki/Automobile_platform">Platforms</a> which has_many Models which has_many Versions (and Platforms has many Version through models). Pretty simple 4 level deep object graph that a car manufacturer might have. A very common set of objects you might want is to know which Platforms are actually in production. Some our outdated, some are future, but you want all the platforms that are currently in production.</p>
<p>Now, I know how I&#8217;d do this, but I commonly see code like this:</p>
<pre><code class="ruby">class Vehicles
  def current_platforms(options = {})
    platforms = platforms.find(:all,
                        :conditions =&gt;
                          ["platforms.on_date &gt;= ? AND platforms.status IN ('open', 'cancelled') AND platforms.cached_inventory_status != ?",
                            Date.today.to_s(:db),
                            Platform.cached_inventory_status(:no_inventory)],
                        <img src='http://bjclark.me/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder =&gt; 'on_date asc, time_note asc',
                        :include =&gt; {:models =&gt; :versions})

    if options[:skip_some_special_case]
      platforms.select { |platform| platform.versions.any? { |offer| !version.special_case} }
    elsif options[:skip_some_other_case]
      platforms.select { |platform| platform.versions.any?(&amp;:other_case?) }
    else
      platforms
    end
  end
end</code></pre>
<p>This code is a great example of my problem with how most folks end up simplifying LoD violations. No where are we chaining methods &#8220;too deep&#8221; or as it gets simplified to are we &#8220;using too many periods&#8221;. We&#8217;ve only used 1 period (because of a has_many :through =&gt;). However, in our if statements, we are tightly coupling our code to the behavior of a class that is 3 siblings away from the one we&#8217;re working in. Nasty. Never should a Platform do operations on, or even know about, a Version.</p>
<p>So why is my example actually worse than something.try(:something_else).try(:a_third)? Well, lets get back to that * I left on &#8220;(actually external [structure])&#8221;.</p>
<p>Most people seem to classify the active_record generated attribute accessors of Rails model classes as &#8220;internal structure&#8221; (Avdi doesn&#8217;t, I should state for correctness). These are most certainly external structure. You can override them and return whatever you&#8217;d like and attributes[:foo] is actually the &#8220;internal&#8221; accessor for all active_record classes. External structure, in every project I&#8217;ve ever worked in, has been the most consistent, least volatile part of the codebases. External structure almost *never* changes, and when it does, it&#8217;s typically *very* easy to change (it&#8217;s not even a refactoring, it&#8217;s just changing the messages exchanged between classes).</p>
<p>My example relies on <em>behavior</em> of a class 3 classes away. If there&#8217;s anything I&#8217;ve learned, it&#8217;s that behavior is always more volatile than structure, and as Avdi points out, LoD really starts hurting as code churns and whatever your LoD relies on changes and becomes more and more complex.</p>
<p>So the big question is, how do we fix this?</p>
<p>It&#8217;s actually a theoretically simple fix, and similar to the fixes in Avdi&#8217;s post: delegate the behavior down the object graph!</p>
<pre><code class="ruby">class Vehicle
  def current_platforms(options={})
    if options[:skip_some_special_case]
      platforms.reject(&amp;:special_case?)
    elsif options[:skip_some_other_case]
      platforms.select(&amp;:other_case?)
    else
      platforms.select(&amp;:regular_case)
    end
  end
end

class Platform
  def regular_case
    ...
  end
  def special_case?
    models.special_case?
  end
  def other_case?
    models.other_case?
  end
end

class Model
  def special_case?
    versions.special_case?
  end
  def other_case?
    versions.other_case?
  end
end

class Version
  def special_case?
    ...
  end
  def other_case?
    ...
  end
end</code></pre>
<p>Now, Platform knows nothing about versions, versions can easily change what defines the &#8220;cases&#8221; without any changes to Platform and ironically, when I made this refactoring to the original source I got this derived example from, it&#8217;s actually *more* efficient. Removing the explicit find that started the original method means that if we&#8217;ve already loaded this object graph, even outside of this method, we can keep reusing it without going to the database.</p>
<p>I hope this helps, and for the love of Demeter, can we stop describing it as &#8220;using too many periods&#8221;?</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/07/law-of-demeter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>XP and Lean Startup in a single image</title>
		<link>http://bjclark.me/2011/06/xp-and-lean-startup-in-a-single-image/</link>
		<comments>http://bjclark.me/2011/06/xp-and-lean-startup-in-a-single-image/#comments</comments>
		<pubDate>Tue, 21 Jun 2011 18:59:24 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[leanstartup]]></category>
		<category><![CDATA[memes]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=228</guid>
		<description><![CDATA[David Bland tweeted something today that I&#8217;ve heard/thought before, but reminded me of what the essence of both XP/Agile and Lean Startup are all about. 1. Identify all of the feedback loops in your startup. 2 Shorten them. June 21, 2011 10:04 am via webReplyRetweetFavorite @davidjbland David J Bland I&#8217;ve distilled this into a single [...]]]></description>
			<content:encoded><![CDATA[<p>David Bland tweeted something today that I&#8217;ve heard/thought before, but reminded me of what the essence of both XP/Agile and Lean Startup are all about.</p>
<p><!-- tweet id : 83218859917717507 --><br />
<style type='text/css'>#bbpBox_83218859917717507 a { text-decoration:none; color:#0040ff; }#bbpBox_83218859917717507 a:hover { text-decoration:underline; }</style>
<div id='bbpBox_83218859917717507' class='bbpBox' style='padding:20px; margin:5px 0; background-color:#ffffff; background-image:url(http://a3.twimg.com/profile_background_images/177847546/pwn_the_code.gif);'>
<div style='background:#fff; padding:10px; margin:0; min-height:48px; color:#380c38; -moz-border-radius:5px; -webkit-border-radius:5px;'><span style='width:100%; font-size:18px; line-height:22px;'>1. Identify all of the feedback loops in your startup. 2 Shorten them.</span>
<div class='bbp-actions' style='font-size:12px; width:100%; padding:5px 0; margin:0 0 10px 0; border-bottom:1px solid #e6e6e6;'><img align='middle' src='http://bjclark.me/wp-content/plugins/twitter-blackbird-pie//images/bird.png' /><a title='tweeted on June 21, 2011 10:04 am' href='http://twitter.com/#!/davidjbland/status/83218859917717507' target='_blank'>June 21, 2011 10:04 am</a> via web<a href='https://twitter.com/intent/tweet?in_reply_to=83218859917717507' class='bbp-action bbp-reply-action' title='Reply'><span><em style='margin-left: 1em;'></em><strong>Reply</strong></span></a><a href='https://twitter.com/intent/retweet?tweet_id=83218859917717507' class='bbp-action bbp-retweet-action' title='Retweet'><span><em style='margin-left: 1em;'></em><strong>Retweet</strong></span></a><a href='https://twitter.com/intent/favorite?tweet_id=83218859917717507' class='bbp-action bbp-favorite-action' title='Favorite'><span><em style='margin-left: 1em;'></em><strong>Favorite</strong></span></a></div>
<div style='float:left; padding:0; margin:0'><a href='http://twitter.com/intent/user?screen_name=davidjbland'><img style='width:48px; height:48px; padding-right:7px; border:none; background:none; margin:0' src='http://a1.twimg.com/profile_images/602255806/david_12_09_small_normal.jpg' /></a></div>
<div style='float:left; padding:0; margin:0'><a style='font-weight:bold' href='http://twitter.com/intent/user?screen_name=davidjbland'>@davidjbland</a>
<div style='margin:0; padding-top:2px'>David J Bland</div>
</div>
<div style='clear:both'></div>
</div>
</div>
<p><!-- end of tweet --></p>
<p>I&#8217;ve distilled this into a single meme image. Print this out and put it on your wall.<br />
<img src="https://img.skitch.com/20110621-bpmk321m9i6g7rd8xt5gixgt52.jpg" alt="Courage Wolf is Agile" /></p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/06/xp-and-lean-startup-in-a-single-image/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking of Turds (A Technological Term)</title>
		<link>http://bjclark.me/2011/02/speaking-of-turds-a-technological-term/</link>
		<comments>http://bjclark.me/2011/02/speaking-of-turds-a-technological-term/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 20:51:40 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[product design]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=218</guid>
		<description><![CDATA[http://www.youtube.com/watch?v=yiJ9fy1qSFI I use the term &#8220;turd&#8221; often when talking about products, either hardware or software but I&#8217;m not always sure people know what I mean. A turd is something your company &#8220;has to do&#8221;. Sometimes they sink and sometimes they float, but they are always mandatory. A turd can be polished and it can be [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">
<p><a href="http://www.youtube.com/watch?v=yiJ9fy1qSFI">http://www.youtube.com/watch?v=yiJ9fy1qSFI</a></p>
</div>
<p>I use the term &#8220;turd&#8221; often when talking about products, either hardware or software but I&#8217;m not always sure people know what I mean.</p>
<p>A turd is something your company &#8220;has to do&#8221;. Sometimes they sink and sometimes they float, but they are always mandatory.</p>
<p>A turd can be polished and it can be of any shape or size, but at it&#8217;s core, it&#8217;s still excrement.</p>
<p>Turds always come from somewhere. Sometimes, usually the ones that float, turds come from good things. The right things. Things like user needs, innovation, obvious holes in the market demanding to be filled.  Many times, however, turds come from bad places, these are usually the ones that sink (and stink). Stinky turds come from fear, they come from reactions to competitors, they come from &#8220;obligations&#8221;.</p>
<p>Everyone makes turds. The iPod Touch is a floating turd. Apple was obligated to make it. How could they resist? They&#8217;ve sold a ton because of the branding and the apps and the advertising, so it&#8217;s a shiny turd, but a turd no less.</p>
<p>Most (all?) of the iPad &#8220;killers&#8221; are turds. They are reactionary. They aren&#8217;t innovations, they are year late catchups powered by software that went from being something new to a turd the day the App Store launched.</p>
<p>The Facebook platform was, in it&#8217;s inception, pretty awesome. It&#8217;s turned in to a turd through, what I can only imagine has been, some epic bikeshedding,  beauracracy and abuse. I bet Zuck would kill it if he could, but instead he&#8217;s &#8220;obligated&#8221; to keep it going.</p>
<p>I don&#8217;t even think turds are bad. Turds can be great. They can be just what a company needs. But lets call a spade, a spade, or a turd.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/02/speaking-of-turds-a-technological-term/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Things I have learned as an artist (no. 1)</title>
		<link>http://bjclark.me/2011/02/things-i-have-learned-as-an-artist-no-1/</link>
		<comments>http://bjclark.me/2011/02/things-i-have-learned-as-an-artist-no-1/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 04:36:43 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Art]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=215</guid>
		<description><![CDATA[At the beginning of every project and the learning of any skill, you always believe you already know what perfection is. This assumption is always false.]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">At the beginning of every project and the learning of any skill, you always believe you already know what perfection is.</div>
<div></div>
<div>This assumption is always false.</div>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/02/things-i-have-learned-as-an-artist-no-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Typography of web applications</title>
		<link>http://bjclark.me/2011/01/typography-of-web-applications/</link>
		<comments>http://bjclark.me/2011/01/typography-of-web-applications/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 22:55:08 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[new twitter]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[typography]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=210</guid>
		<description><![CDATA[One of the hardest things about designing web applications is presenting the multitude of types of information that is necessary at any one time. What do you display? What do you leave out? What information is more or less important than other information? If a piece of information is actionable, how do you visually inform the user of that?

Recently Twitter redesigned their interface using a new 2 panel layout where the sidebar dynamically changes, allowing for deeper inspection into the tweets that show up in your timeline. From a design standpoint there are a number of things that are great about this. The proportions (using the golden ratio) are excellent. The metaphor of a slide out panel is excellent. The exprience over "old Twitter" for reading conversation is vastly better.

However, there are 2 things that specifically bug me about the new design:  what I'd call the over stylization of the content and an over abundance of information.]]></description>
			<content:encoded><![CDATA[<p>One of the hardest things about designing web applications is presenting the <em>multitude of types</em> of information that is necessary at any one time. What do you display? What do you leave out? What information is more or less important than other information? If a piece of information is actionable, how do you visually inform the user of that?</p>
<p>Recently Twitter redesigned their interface using a new 2 panel layout where the sidebar dynamically changes, allowing for deeper inspection into the tweets that show up in your timeline. From a design standpoint there are a number of things that are great about this. The proportions (using the golden ratio) are excellent. The metaphor of a slide out panel is excellent. The exprience over &#8220;old Twitter&#8221; for reading conversation is vastly better.</p>
<p>However, there are 2 things that specifically bug me about the new design:  what I&#8217;d call the <em>over stylization</em> of the content and an over abundance of information.</p>
<p style="text-align: center;"><a href="http://bjclark.me/wp-content/uploads/2011/01/4-Twitter-_-Home-2.jpg"><img class="size-full wp-image-211 aligncenter" title="new twitter 1" src="http://bjclark.me/wp-content/uploads/2011/01/4-Twitter-_-Home-2.jpg" alt="New Twitter conversation view." width="492" height="490" /></a></p>
<p style="text-align: left;">This is a conversation in the side panel between two people I know. The first problem is that I think this is too much information. Here is what I see here: close link with icon, 3 tweets in two distinct styles with avatars, usernames, real names, timestamps, API client names and conversation links that link to the same conversation I&#8217;m viewing. There is also a user profile, which is in the same style as a tweet except the user&#8217;s bio is in italics. There is also links to use the original tweet in all the functions Twitter provides and the panel even goes on to list out other tweets from @bleything, however I have chosen to crop those out. Keeping in mind that my original intention was to view a conversation, and I came upon that conversation by clicking on a link in a original tweet, my goals are fulfilled but I&#8217;m also bombarded with more extraneous information than the original conversation contained.</p>
<p style="text-align: left;">Second, although there are probably less than 1000 characters here, and less than 420 characters of the information I requested when I wanted to view the conversation, there are no less than 12 distinct combinations of font weight, color and size.</p>
<p style="text-align: left;"><a href="http://bjclark.me/wp-content/uploads/2011/01/4-Twitter-_-Home-1-1.jpg"><img class="aligncenter size-full wp-image-212" title="new twitter 2" src="http://bjclark.me/wp-content/uploads/2011/01/4-Twitter-_-Home-1-1.jpg" alt="Annotating a screen shot of new twitter to show the 12 distinct font styles." width="492" height="487" /></a></p>
<p style="text-align: left;">Lets compare this with a &#8220;conversation view&#8221; from the Echofon Mac desktop app.</p>
<p style="text-align: left;"><a href="http://bjclark.me/wp-content/uploads/2011/01/Echofon.jpg"><img class="aligncenter size-full wp-image-213" title="Echofon" src="http://bjclark.me/wp-content/uploads/2011/01/Echofon.jpg" alt="Echofon conversation view" width="491" height="251" /></a>I find Echofon&#8217;s conversation much easier to read, and if I want more information, such as the API Client used to post the tweet or the user&#8217;s bio, I don&#8217;t mind digging deeper through the pathways I already know exist in the app. If I like to do something with one of the tweets, hidden controls appear when I mouse over. And even though there are graphics, the UI here is cleaner and only contains 2 text styles.  Literally every piece of information or action provided in the new Twitter conversation is accessible via either 1 mouse click or hover.</p>
<p style="text-align: left;">Designing applications is always about more than what the app look like. It&#8217;s how the app works, what information it presents, and making sure the user can easily and clearly achieve their goals.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/01/typography-of-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pro Tip: Encapsulate logic in Rails Views for maintainability</title>
		<link>http://bjclark.me/2011/01/pro-tip-encapsulate-logic-in-rails-views-for-maintainability/</link>
		<comments>http://bjclark.me/2011/01/pro-tip-encapsulate-logic-in-rails-views-for-maintainability/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 20:39:13 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[protip]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[views]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=196</guid>
		<description><![CDATA[A Rails view anti-pattern is that they very quickly turn into a nasty tangle of conditional html blocks. Example: &#60;% if logged_in? &#038;&#038; @user == current_user %&#62; Simple example, but what is the intention of that code? Why are you really checking for? Give that state a name. Change that to: def viewing_own_profile(user) logged_in? &#038;&#038; [...]]]></description>
			<content:encoded><![CDATA[<p>A Rails view anti-pattern is that they very quickly turn into a nasty tangle of conditional html blocks.</p>
<p>Example:</p>
<pre><code class="ruby">
&lt;% if logged_in? &#038;&#038; @user == current_user %&gt;
</code></pre>
<p>Simple example, but what is the intention of that code? Why are you really checking for? Give that state a name.</p>
<p>Change that to:</p>
<pre><code class="ruby">
def viewing_own_profile(user)
  logged_in? &#038;&#038; user == current_user
end

&lt;% if viewing_own_profile(@user) %&gt;
</code></pre>
<p>Now you can test that helper method without resorting to rendering a view and parsing it to check if elements exist, the state you care about is named and the intention is clear.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2011/01/pro-tip-encapsulate-logic-in-rails-views-for-maintainability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jambox by Jawbone Review</title>
		<link>http://bjclark.me/2010/11/jambox-by-jawbone-review/</link>
		<comments>http://bjclark.me/2010/11/jambox-by-jawbone-review/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 06:17:30 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[jambox]]></category>
		<category><![CDATA[jawbone]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=170</guid>
		<description><![CDATA["Ohhhh! It's the hipster speaker!" - @didip

That's what my co-worker said when he walked into the office this morning. Waiting for me when I got to work was the new Jambox by Jawbone. You may remember the video for the Jambox that went around the interwebs that featured a hipster looking dude and set the tone that these speakers that could replace your stereo as well as your conference phone in your office. Well guess what? I tend to be on daily of conference calls (via IAX via Zoiper) and we really needed a stereo for our PDX Studio, so a pre-order was made and the Jambox was delivered!]]></description>
			<content:encoded><![CDATA[<blockquote><p>&#8220;Ohhhh! It&#8217;s the hipster speaker!&#8221; &#8211; @didip</p></blockquote>
<p>That&#8217;s what my co-worker said when he walked into the office this morning. Waiting for me when I got to work was the new Jambox by Jawbone. You may remember the <a href="http://www.youtube.com/watch?v=XgC3zjNH1oU" target="_blank">video</a> for the Jambox that went around the interwebs that featured a hipster looking dude and set the tone that these speakers that could replace your stereo as well as your conference phone in your office. Well guess what? I tend to be on daily of conference calls (via IAX via Zoiper) and we really needed a stereo for our PDX Studio, so a pre-order was made and the Jambox was delivered!</p>

			<!-- generated by showtime WP plugin -->
			<script type='text/javascript'>
			
				var flashvars = {
					
				xml 			: 'http://bjclark.me/wp-content/plugins/showtime-slideshow/showtime/getxml.php?attr=flickr^aHR0cCUzQSUyRiUyRmFwaS5mbGlja3IuY29tJTJGc2VydmljZXMlMkZmZWVkcyUyRnBob3Rvc2V0LmduZSUzRnNldCUzRDcyMTU3NjI1Mzk3NjM4MDE2JTI2YW1wJTNCbnNpZCUzRDcxODgxNzI3JTQwTjAwJTI2YW1wJTNCbGFuZyUzRGVuLXVz*order^reverse*source^medium*sourcehd^large*',
				
				width           : '640',
				height          : '320',
				classid         : 'st_0',

				rotationtime    : '5',
				transition      : 'Flip',
				transitiontime  : '1',
				transitionease  : 'LinearEaseNone',
				autoplay        : 'on',
				showcontrols    : '',
				controls        : '0',
				textbgcolor     : '',

				showtext        : 'on',
				showalt         : '',
				shuffle         : '',
				scale           : 'showAll',
				target          : '_self'			
				
				
				};
				
				var params = {};
				params.allowFullScreen = 'true';
				params.bgcolor = '#000000';		
				params.quality = 'autohigh';		
				params.wmode = 'window';
				//params.base = 'dirname(__FILE__)';
				//params.allowScriptAccess = 'local';
			
				var attributes = {};
				attributes.styleclass = 'showtime';
												
				swfobject.embedSWF ('http://bjclark.me/wp-content/plugins/showtime-slideshow/showtime/st16.swf', 'st_0', '640', '320', '10.0.0', 'false', flashvars, params, attributes);
			</script>
	
					
			<!-- alternative content -->	
			<div id='st_0'></div>
					
			

<p>More <a href="http://www.flickr.com/photos/robotdeathsquad/sets/72157625397638016/">photos of the Jambox</a> on my flickr.</p>
<p>The first thing you&#8217;ll notice is that it comes in a shoe box (hipster) with a screen printed boombox on the top. I will admit, the design and packaging is very apple, but urban hipster instead of the modernist-chic of Jonathan Ivey, and it&#8217;s pretty sexy. Upon taking the top off, I took out the Jambox and put it on the desk and tried to turn it on, nada. This thing doesn&#8217;t seem to come with a charge. So I hooked it up and pushed the top button, again, nothing. Finally I noticed there&#8217;s a sliding switch on the side, slid that on, and it announced it was ready to pair. The Jambox seems to have a few status messages that are spoken aloud to you. I like this.</p>
<p>I also love the size and weight. The Jambox is TINY! It&#8217;s smaller than a chipotle burrito. It&#8217;s lighter too!</p>
<p>It was pretty easy to get the Jambox to initially pair with my Macbook Pro (10.6.5 fwiw). I fired up iTunes and played some toons and it sounded terrible! I was a little bummed, but I soldiered on. My co-worker and I started trying to connect other devices, my iPhone, my MBP but using Zoiper to make a call, and in this process we figured out that we had the Jambox sitting on it&#8217;s side! Looking back, I can see how they intend for you to use it, but my co-worker and I are pretty smart guys (heck, he&#8217;s even got a CS degree!) and we had literally no idea which end was up. Here&#8217;s the good news, when you do get the Jambox right side up, it sounds <strong>awesome</strong>.</p>
<p>Let me tell you a little about our office. It&#8217;s got 16 foot ceilings, it&#8217;s about 12 x 12 and it&#8217;s one of the more echo-y places I&#8217;ve ever been. Using my trusty Harmon Kardon iSticks, audio sounds pretty terrible in this office. However the Jambox actually lives up to it&#8217;s marketing. For a tiny (this thing is just slightly longer than a sharpie), wireless, and battery powered speaker it sounds great! It&#8217;s got so much bass, it makes my desk vibrate and will even dance across the table. And surprisingly enough, it&#8217;s actually less echo-y in our little studio than the multi-hundered dollar, USB speaker system.</p>
<p>As a speaker phone, I haven&#8217;t used it for any long meetings yet, but initial tests are great. In our cave, using the built in input and output of a MacBook Pro results in terrible echo and looping even in Apple&#8217;s iChat (which does noise canceling). The Jambox exhibited none of this behavior. I&#8217;ll tweet more about this when I use it tomorrow on a few hour-long calls. Certainly, the on-board echo canceling Jawbone is known for is very nice on this unit.</p>
<p>However, it&#8217;s not all unicorns and rainbows: Bluetooth audio still kinda sucks. I spent a fair amount of time trying to reboot the Jambox, trying to get the computer to forget it so that the iPhone would notice it (when it did, it worked/sounded awesome), and quite a bit of time trying to make the MBP recognize the Jambox as an audio input/output device. This was not easy and led to much frustration which turned in to, at the end of the day, somehow having the bluetooth in my MBP completely turn off necessitating a reboot of the computer to get bluetooth to turn back on again (annoying when you&#8217;re also using a bt mouse). By far, the biggest letdown of an otherwise satisfying user experience, is that using it wirelessly, with multiple devices, totally sucks. The other weird thing is that the Jambox shows up as 2 types of outputs, one a &#8220;headset&#8221; and one a &#8220;speaker&#8221;. I don&#8217;t know when to use which, or what the ramifications are of doing either. Also, I had the absolute <strong>worst </strong>luck trying to get the Jambox to work with Zoiper. I think the final combination was, turn on the Jambox, pair with the macbook pro, choose it as an input/output, and finally start up Zoiper (with the Jambox already programmed as the input/output in the preferences). How this will work when I use Zoiper with headphones later on, we&#8217;ll see.</p>
<p>Overall, is it worth $200? I&#8217;d say the jury is still out. I find it hard to recommend it at this point, because the bluetooth stuff seems like completely voodoo to get working, but maybe after I better figure out pairing with different devices I&#8217;ll change my mind. For the price, you can buy some seriously good speakers, and its hard to tell how Apple&#8217;s Airplay technology is going to shake out on the speaker-system front (numerous manufacturers have announced support, but I haven&#8217;t seen any products hit the market). I certainly would find wifi based speakers more appealing, but I doubt we&#8217;ll see Airplay speakers that can also work as a noise canceling speaker phone for a small office/conference room.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2010/11/jambox-by-jawbone-review/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>From Zero to Rails Hero in 11 Easy Steps (Installing Rails on OS X 10.6.5)</title>
		<link>http://bjclark.me/2010/11/from-zero-to-rails-hero-in-11-easy-steps/</link>
		<comments>http://bjclark.me/2010/11/from-zero-to-rails-hero-in-11-easy-steps/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 06:59:58 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://bjclark.me/?p=159</guid>
		<description><![CDATA[This is the easiest, fastest and best-to-develop-in way to get a rails dev stack up and running on OS X 10.6 (Snow Leopard). I actually find that it&#8217;s pretty easy, if everything is done in the right order. Install XCode Install Homebrew $ ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)" Install git using homebrew $ brew install git [...]]]></description>
			<content:encoded><![CDATA[<p>This is the easiest, fastest and best-to-develop-in way to get a rails dev stack up and running on OS X 10.6 (Snow Leopard).</p>
<p>I actually find that it&#8217;s pretty easy, if everything is done in the right order.</p>
<ol>
<li>Install <a href="http://developer.apple.com/devcenter/mac/login.action" target="_blank">XCode</a></li>
<li>Install Homebrew
<pre><code>$ ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"</code></pre>
</li>
<li>Install git using homebrew
<pre><code>$ brew install git</code></pre>
</li>
<li>Install mysql using homebrew
<pre><code>$ brew install mysql</code></pre>
</li>
<li>Install rvm (and follow the instructions to set up bash and don&#8217;t forget to open a new terminal window)
<pre><code>$ bash &lt; &lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )</code></pre>
</li>
<li>Install Ruby Enterprise Edition
<pre><code>$ rvm install ree</code></pre>
</li>
<li>Make REE the default Ruby
<pre><code>$ rvm use ree --default</code></pre>
</li>
<li>Tell rubygems to not install rdocs<br />
Put the following lines in ~/.gemrc</p>
<pre><code>install: --no-rdoc --no-ri
update: --no-rdoc --no-ri</code></pre>
</li>
<li> Install Passenger
<pre><code>$ gem install passenger</code></pre>
<p>Now follow that up by running the install script (and follow the directions)</p>
<pre><code>$ ./passenger-install-apache2-module</code></pre>
<p>At the end of the install process it will give you instructions to add 3 lines to the &#8220;Apache configuration file&#8221;, but it won&#8217;t tell you *where* your apache config file is. It&#8217;s at /etc/apache2/httpd.conf</li>
<li>Restart Apache<br />
At this point, if you&#8217;re using 10.6.5, you might do a sudo /etc/apachectl restart and run into the following error:<br />
/usr/sbin/apachectl: line 82: ulimit: open files: cannot modify limit: Invalid argumentTo fix this, edit /usr/sbin/apachectl and change <span style="font-family: 'andale mono', 'lucida console', monospace; color: #525252;">ULIMIT_MAX_FILES </span>to an empty string.</p>
<p>Now you can restart apache.</li>
<li>Install PassengerPane 1.3 <a href="http://www.fngtps.com/files/2/2009/09/PassengerPane-1.3.tgz">www.fngtps.com/files/2/2009/09/PassengerPane-1.3.tgz</a></li>
</ol>
<p>BOOM! Done.</p>
<p>Well, for me, I had to `gem install isolate` and Rubymine and then I was done, but you get the idea. Just load up the Passenger Preference Pane, point at site at a rails project on your hard drive, and load it up in your browser. Assuming your rails app will boot, you should be good to go!</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2010/11/from-zero-to-rails-hero-in-11-easy-steps/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A trip to Pasadena in August</title>
		<link>http://bjclark.me/2010/07/a-trip-to-pasadena-in-august/</link>
		<comments>http://bjclark.me/2010/07/a-trip-to-pasadena-in-august/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 21:51:09 +0000</pubDate>
		<dc:creator>BJ Clark</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bjclark.me/2010/07/a-trip-to-pasadena-in-august/</guid>
		<description><![CDATA[I&#8217;m taking a trip to Pasadena between August 4th and August 5th.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m taking <a href='http://dplr.it/guest/6264a8a0a2cd38bb437b'>a trip to Pasadena</a> between August 4th and August 5th.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjclark.me/2010/07/a-trip-to-pasadena-in-august/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.493 seconds -->
<!-- Cached page served by WP-Cache -->

