<?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>Coffee on the Keyboard</title>
	<atom:link href="http://coffeeonthekeyboard.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://coffeeonthekeyboard.com</link>
	<description>Technical 2.0</description>
	<lastBuildDate>Thu, 02 Jul 2009 17:05:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WP: Better Search Widget 1.1</title>
		<link>http://coffeeonthekeyboard.com/wp-better-search-widget-1-1-232/</link>
		<comments>http://coffeeonthekeyboard.com/wp-better-search-widget-1-1-232/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 17:05:05 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=232</guid>
		<description><![CDATA[Better Search Widget 1.1 is a significant upgrade to Better Search Widget that adds new features and fixes an old bug with internationalization.
Features
(New features in bold.)

Optional default value.
Optional, custom widget title.
Optional onfocus and onblur listeners.
Optional, customizable focus and blur colors.
Custom button value.
Custom field size.

The built-in search widget has only one of these features, the optional, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://coffeeonthekeyboard.com/wp-content/uploads/2009/07/better-search-widget.zip">Better Search Widget 1.1</a> is a significant upgrade to <a href="http://coffeeonthekeyboard.com/wp-plugin-better-search-widget-113/" title="Better Search Widget">Better Search Widget</a> that adds new features and fixes an old bug with internationalization.</p>
<h3>Features</h3>
<p>(New features in bold.)</p>
<ul>
<li><strong>Optional default value</strong>.</li>
<li><strong>Optional,</strong> custom widget title<strong>.</strong></li>
<li><strong>Optional onfocus and onblur listeners.</strong></li>
<li><strong>Optional, customizable focus and blur colors.</strong></li>
<li>Custom button value.</li>
<li>Custom field size.</li>
</ul>
<p>The built-in search widget has only one of these features, the optional, custom title.</p>
<h4>Onfocus and Onblur</h4>
<p>In order to use the blur and focus colors, you must enable the onfocus and onblur event listeners. In order to use the listeners, you must specify a default value (otherwise none of this makes sense). Here&#8217;s an example:</p>
<div style="border: 1px solid #333; margin: 0.5em auto; padding: 0.7em 0; width: 50%; text-align: center;">
<form>
<input style="color: #999; width: 80%;" type="text" value="Default" onfocus="this.style.color='#333';if('Default'==this.value)this.value='';" onblur="if(''==this.value){this.style.color='#999';this.value='Default'}" /></form>
</div>
<h3>Bug Fixes</h3>
<p>A pretty serious typo meant that none of the internationalization code worked correctly. This has been fixed, and en_US, en_GB, and fr_FR localizations are available. de_DE is coming. If you&#8217;d like to translate, there is a .pot file included in the languages directory.</p>
<h3>License</h3>
<p>Better Search Widget is released under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>. If you use it, or have suggestions for new features or bug fixes, let me know!</p>
<h3>Getting It</h3>
<p>You can download <a href="http://coffeeonthekeyboard.com/wp-content/uploads/2009/07/better-search-widget.zip">Better Search Widget 1.1</a> now in a Zip file. Or, to save yourself some trouble,  you can check it out of Subversion from</p>
<pre>svn co svn://jamessocol.com/better-search-widget/tags/1.1.0 ./better-search-widget</pre>
<p>(Run that in your <code>wp-content/plugins</code> directory.) Subversion will make it easiest to upgrade later.</p>
<h3>Roadmap</h3>
<p>Soon, though probably not today, I will be releasing Better Search Widget 2, which will take advantage of the new Widget API in WordPress 2.8. This will add support for multiple instances of the widget, but will require at least WordPress 2.8. You should upgrade, anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/wp-better-search-widget-1-1-232/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Widget l10n</title>
		<link>http://coffeeonthekeyboard.com/widget-l10n-230/</link>
		<comments>http://coffeeonthekeyboard.com/widget-l10n-230/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 04:36:43 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=230</guid>
		<description><![CDATA[I spent some of today working on bringing a couple of WordPress widgets up-to-date (Better Search and Most Comments) only to discover there is a new widget API. I guess I haven&#8217;t been paying attention.
I&#8217;ll probably start some 2.0 branches tomorrow to take advantage of the new API. I wish I didn&#8217;t know how many [...]]]></description>
			<content:encoded><![CDATA[<p>I spent some of today working on bringing a couple of WordPress widgets up-to-date (<a href="http://jamessocol.com/projects/better-search-widget.php">Better Search</a> and <a href="http://jamessocol.com/projects/most-comments-widget.php">Most Comments</a>) only to discover there is a <a href="http://codex.wordpress.org/Widgets_API#Developing_Widgets_on_2.8.2B">new widget API</a>. I guess I haven&#8217;t been paying attention.</p>
<p>I&#8217;ll probably start some 2.0 branches tomorrow to take advantage of the new API. I wish I didn&#8217;t know how many people don&#8217;t keep their WordPress installations up to date, so I wouldn&#8217;t care about backwards compatibility.</p>
<p>At least both widgets got nice new, and functional, internationalization (i18n) code and new localization (l10n) files.</p>
<p>And BSW got a good feature update, incorporating some suggestions from <a href="http://mjml.de/">Marco Jung</a>, who is also, kindly, doing a German localization, and a few of my own. The built-in search widget has stepped up it&#8217;s game, and fixed the thing BSW was originally designed to fix (no widget title) so I have a higher bar to clear to justify the name &#8220;<em>Better</em> Search Widget.&#8221;</p>
<p>I&#8217;ll write up the new features tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/widget-l10n-230/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Personal Update</title>
		<link>http://coffeeonthekeyboard.com/a-personal-update-228/</link>
		<comments>http://coffeeonthekeyboard.com/a-personal-update-228/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 04:23:15 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=228</guid>
		<description><![CDATA[Most of my blog visitors are people trickling in from Google with questions about rebuilding PHP on RHEL, connecting PHP, IIS6 and SQL Server, or, inexplicably, looking for info on the game Crysis.
I should warn, a lot of that stuff is out of date. And I never did end up buying Crysis. (Gaming at 640&#215;480 [...]]]></description>
			<content:encoded><![CDATA[<p>Most of my blog visitors are people trickling in from Google with questions about <a href="http://coffeeonthekeyboard.com/how-to-upgrade-or-recompile-php-on-rhel5-59/" title="rebuilding PHP on RHEL">rebuilding PHP on RHEL</a>, <a href="http://coffeeonthekeyboard.com/connecting-php-iis-6-and-sql-server-2005-129/" title="connecting PHP, IIS6 and SQL Server">connecting PHP, IIS6 and SQL Server</a>, or, inexplicably, looking for info on the game <a href="http://coffeeonthekeyboard.com/crysis-58/" title="Crysis">Crysis</a>.</p>
<p>I should warn, a lot of that stuff is out of date. And I never did end up buying Crysis. (Gaming at 640&#215;480 just isn&#8217;t that fun anymore.)</p>
<p>Anyway, given that traffic profile, I doubt most visitors will care about this. But, in case I&#8217;m wrong, and I often am, I thought you deserved to know about some relatively large changes with me lately.</p>
<p>The first and biggest: I no longer work at Michigan State University. I worked there for a year and a half as an student, and when I graduated, they kept me on as a temporary employee and then offered me a year-long contract position. That contract expired at the end of May—literally: May 31st would&#8217;ve been my last day if it hadn&#8217;t been a Sunday.</p>
<p>My month-to-month lease renewed on June 3rd, so I had a choice of moving everything out very quickly or paying for an extra month. Since I was only bugging out about 100 miles to <a href="http://speedchange.blogspot.com/">my father&#8217;s</a> place, I decided to get out quickly. (Nice for the landlord: there were already people coming to see and apply for the place before I was done packing.)</p>
<p>And then the last week of May I needed to fly out to California.</p>
<p>So in the span of a week, I flew to California and back, ended my job, and moved. Quite a turbulent time. A lot of things, like Twitter and this blog, fell by the wayside. Don&#8217;t worry, though. I have a post about semantic form markup that&#8217;s almost ready to go.</p>
<p>The job thing: I was not particularly excited about staying in the Lansing area when it was offered, but I took it because, basically, everyone told me to. Really, I only ended up staying about 9 months longer than I&#8217;d planned, but I needed to get out of the area. In the future, I may write about my experiences as support staff in a university environment (hint: I didn&#8217;t love it) but for now, know that leaving was a very positive thing for me in a lot of ways.</p>
<p>When you start to feel like <a href="http://www.imdb.com/name/nm0000190/">Matthew McConaughey</a> in <a href="http://www.imdb.com/title/tt0106677/">Dazed and Confused</a> (&#8221;That&#8217;s what I love about these undergrads, man. I get older; they stay the same age&#8230;&#8221;) it&#8217;s time to move on.</p>
<p>And, while I&#8217;m not yet quite ready to talk about it, it looks like the job situation will work out very well, and very quickly. Of course, I&#8217;ll have to move again.</p>
<p>That&#8217;s the story. Or at least as much as I&#8217;ll tell right now. Now for some technical mumbo-jumbo.</p>
<p>I&#8217;ve been working on a little project—though not in the past three weeks—called <a href="http://svn.jamessocol.com/cocode">Cocode</a>. It&#8217;s an open-source pastebin app that runs on my <a href="http://svn.jamessocol.com/maveric">PHP framework, Maveric</a>. Well, not quite a pastebin. More accurately, it&#8217;s a tool to support internal code review. It supports user authentication, comments on code snippets, and, of course, revisions with diffs and syntax highlighting.</p>
<p>Working on Cocode has given me a good reason to do some development on Maveric, itself. I&#8217;ve added some neat <abbr title="Object-Relational Mapping">ORM</abbr> features and am working on a real database abstraction layer. I also want to improve routing and several other ugly bits, but, you know, one thing at a time. The changes to Maveric give me a good reason to go back and rework the application layer of <a href="http://todaysmeet.com/">Today&#8217;s Meet</a>, as well, though I haven&#8217;t done it yet. What a good time to add some of the features people request!</p>
<p>You can check out <a href="http://svn.jamessocol.com/maveric">Maveric</a> and <a href="http://svn.jamessocol.com/cocode">Cocode</a> from Subversion, if you&#8217;re curious. And if you&#8217;re a PHP developer who wants to contribute, please <a href="mailto:me@jamessocol.com">let me know</a>. I would certainly appreciate the help and a fresh perspective. I&#8217;ll post more about Cocode soon.</p>
<p>Finally, I&#8217;m working on a little WordPress plugin to help with the new rash of irrelevant comment spam I&#8217;m getting. (You know the kind: they just say &#8220;Great Psot!&#8221; and their URL is the important part.) I&#8217;ll post about that one, too.</p>
<p>There&#8217;s my life, lately, both the coding and non-coding aspects. I hope you&#8217;ve enjoyed this brief, personal interlude. Next up, you&#8217;re regularly scheduled geekery and social media name-calling—except on the West Coast, where you&#8217;re local news is up next.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/a-personal-update-228/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript: Private Static Members, Part 2</title>
		<link>http://coffeeonthekeyboard.com/javascript-private-static-members-part-2-218/</link>
		<comments>http://coffeeonthekeyboard.com/javascript-private-static-members-part-2-218/#comments</comments>
		<pubDate>Tue, 19 May 2009 14:55:36 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Front-end]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=218</guid>
		<description><![CDATA[Finally, it&#8217;s time to finish up the lesson on private static members and methods in JavaScript.
Last time, I introduced the technique of creating and immediately executing a function, using parentheses. I talked a little about returning a function and storing it in a variable.
var myFunc = &#40;function &#40;&#41; &#123;
&#160; return function &#40;&#41; &#123;
&#160; &#160; alert&#40;&#34;Hello, [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, it&#8217;s time to finish up the lesson on private static members and methods in JavaScript.</p>
<p><a href="http://coffeeonthekeyboard.com/javascript-private-static-members-part-1-208/">Last time</a>, I introduced the technique of creating and immediately executing a function, using parentheses. I talked a little about <em>returning</em> a function and storing it in a variable.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> myFunc = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Hello, World!&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw3">alert</span><span class="br0">&#40;</span>myFunc<span class="br0">&#41;</span>; <span class="co1">// &quot;function () &#8230; &quot;</span></p>
<p>myFunc<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// Hello, World!</span></div>
<p><span id="more-218"></span><br />
There are a lot of things you can do with this trick, like create interesting <a href="http://coffeeonthekeyboard.com/firefox-open-in-blank-tab-197/">bookmarklets</a>. But let&#8217;s see how you can use it to protect information on the class level.</p>
<p>Here we&#8217;ll take advantage of JavaScript&#8217;s scope behavior. Remember that a function uses the variables where it is <em>defined</em>, not executed. Perhaps a better example&#8230;</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> myFunc = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="kw2">var</span> message = <span class="st0">&quot;I&#8217;m hidden.&quot;</span>;<br />
&nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span>message<span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw2">var</span> message = <span class="st0">&quot;I&#8217;m visible.&quot;</span>;</p>
<p>myFunc<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// &quot;I&#8217;m hidden.&quot;</span></div>
<p>We can see that the inner function (which is returned from the outer function and set to <code>myFunc</code>) uses the value of <code>message</code> from the block where it was defined, not executed.</p>
<p>Now you should be able to see where this is going. Let&#8217;s look at a more complex example, extended from the <a href="http://coffeeonthekeyboard.com/private-variables-in-javascript-177/">first part</a>:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> Product = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNumRegex = <span class="re0">/^\d<span class="br0">&#123;</span><span class="nu0">4</span><span class="br0">&#125;</span>\-\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span>$/</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span> num <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> partNum = <span class="kw2">null</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">setPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span> n <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>partNumRegex.<span class="me1">test</span><span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partNum = n;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">getPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> partNum;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>num<span class="br0">&#41;</span> <span class="kw1">this</span>.<span class="me1">setPartNum</span><span class="br0">&#40;</span>num<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">this</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw2">var</span> car = <span class="kw2">new</span> Product;<br />
car.<span class="me1">setPartNum</span><span class="br0">&#40;</span><span class="st0">&#8216;1234-56&#8242;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw2">var</span> table = <span class="kw2">new</span> Product;<br />
table.<span class="me1">setPartNum</span><span class="br0">&#40;</span><span class="st0">&#8216;345678&#8242;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Car: &quot;</span>+car.<span class="me1">getPartNum</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="co1">// &quot;Car: 1234-56&quot;</span><br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Table: &quot;</span>+table.<span class="me1">getPartNum</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="co1">// &quot;Table: null&quot;</span></div>
<p>What&#8217;s the advantage here? The variable <code>partNumRegex</code> is <em>not</em> copied by the <code>new</code> operator. In a small example like this, there is not much benefit, but if you had hundreds of <code>Product</code> objects, you could save a significant amount of memory.</p>
<p>There are a few major drawbacks: a public static (class) method cannot access a private static method or variable. For example:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> Product = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNumRegex = <span class="re0">/^\d<span class="br0">&#123;</span><span class="nu0">4</span><span class="br0">&#125;</span>\-\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span>$/</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// snip</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>Product.<span class="me1">validPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span>num<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>partNumRegex.<span class="me1">test</span><span class="br0">&#40;</span>num<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1">// (1)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
<span class="br0">&#125;</span></div>
<p>The class method <code>validPartNum</code> has no access to the private class variable <code>partNumRegex</code>, and so will throw an error at (1). Adding an accessor <em>must</em> be done on the <em>instance</em>, not the class, like so:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> Product = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNumRegex = <span class="re0">/^\d<span class="br0">&#123;</span><span class="nu0">4</span><span class="br0">&#125;</span>\-\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span>$/</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">getPartNumRegex</span> = <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> partNumRegex;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// snip</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p>But then you cannot access the private variable without first creating an instance of the class, and the accessor function is copied with the <code>new</code> operator. New methods added to the <code>Product.prototype</code> object are likewise unable to access the private static variables. This is a limitation of JavaScript.</p>
<p>Even with these limitations, the ability to hide implementation behind an agreed-upon interface is powerful. (JavaScript doesn&#8217;t actually have interfaces, but you can just write it down.) Behind the scenes, you could load new data via Ajax, without ever exposing your Ajax method to that new guy down the hall who likes to misuse everything he can:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> Product = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNumRegex = <span class="re0">/^\d<span class="br0">&#123;</span><span class="nu0">4</span><span class="br0">&#125;</span>\-\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span>$/</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// private static function, not copied with &quot;new&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">function</span> loadPartData<span class="br0">&#40;</span>partNum<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// load data via Ajax</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> partNum = <span class="kw2">null</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// snip</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">setPartNum</span><span class="br0">&#40;</span>num<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>partNumRegex.<span class="me1">test</span><span class="br0">&#40;</span>num<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partNum = num;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> data = loadPartData<span class="br0">&#40;</span>partNum<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">productName</span> = data.<span class="me1">productName</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">price</span> = data.<span class="me1">price</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// snip</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p>That&#8217;s it for now. I owe most of these three articles to the book <a href="http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X">Pro JavaScript Design Patterns</a>, by Ross Harmes and Dustin Diaz. Those two are geniuses, and anyone who wants to be a better JavaScript programmer would do well to pick up their book.</p>
<p>Next up, I&#8217;ll argue why the <code>&lt;dl&gt;</code> tag is a good way to display forms semantically.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/javascript-private-static-members-part-2-218/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Social Media Marketing: This is your Chance</title>
		<link>http://coffeeonthekeyboard.com/social-media-marketing-this-is-your-chance-215/</link>
		<comments>http://coffeeonthekeyboard.com/social-media-marketing-this-is-your-chance-215/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 16:49:50 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Social Media]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=215</guid>
		<description><![CDATA[If I could&#8217;ve sat down with Chris Brogan and Laura Fitton six months ago and asked them one thing, it would have been: &#8220;Who, exactly, are you marketing to?&#8221;
There has always been a small thorn in my paw about social media marketing. It&#8217;s the same thing that bothers me when people come on TV and [...]]]></description>
			<content:encoded><![CDATA[<p>If I could&#8217;ve sat down with <a href="http://www.chrisbrogan.com/">Chris Brogan</a> and <a href="http://pistachioconsulting.com/">Laura Fitton</a> six months ago and asked them one thing, it would have been: &#8220;Who, exactly, are you marketing to?&#8221;</p>
<p>There has always been a small thorn in my paw about social media marketing. It&#8217;s the same thing that bothers me when people come on TV and promise to help make you rich. All you have to do is&#8230; sell a book that promises to make people rich! It&#8217;s the same feeling I get when I read <a href="http://www.problogger.net/">Problogger</a> and wonder: &#8220;Do I want to listen to advice from a blog about blogging? Would I do better to listen to someone like <a href="http://www.codinghorror.com/blog/">Jeff Atwood</a>?&#8221;<span id="more-215"></span></p>
<p>For months—years—the &#8220;social media space&#8221; has been dominated by, well, social media users. There are lots of people, from Brogan and Pistachio on down, promising to help you leverage tools like <a href="http://twitter.com/">Twitter</a>. But who was the audience on Twitter? Early-adopters. Geeks. Other &#8220;social media marketers.&#8221;</p>
<p>Of course Chris Brogan can sell himself on Twitter: it was his ideal audience. But when it comes to marketing the end product, who&#8217;s listening?</p>
<p>Twitter use has <a href="http://www.techcrunch.com/2009/04/24/twitter-eats-world-global-visitors-shoot-up-to-19-million/">skyrocketed</a> over the last 9 or 10 months. Once the morning shows started talking about Twitter (unfortunately, giving very <a href="http://www.mcall.com/news/opinion/anotherview/all-point.6868702apr24,0,6909055.story">false impressions</a>) the cascade was probably inevitable. And the people who are joining now are not the same people who joined a year and a half ago.</p>
<p>The time for social media marketers—the real ones, dealing with consumers, not meta-marketers selling advice on selling—to prove themselves is <strong>right now</strong>.</p>
<p>This is your chance.</p>
<p>Prove to me that this can work; that what you do is worth it.</p>
<p>I don&#8217;t mean to pick on Chris Brogan. I&#8217;m sure his company, <a href="http://crosstechmedia.com/">CrossTech Media</a>, has a portfolio of successful campaigns. What <em>doesn&#8217;t</em> impress me is convincing the early adopters of the potential of the space. If there&#8217;s a more apt example of &#8220;preaching to the choir,&#8221; I don&#8217;t know it.</p>
<p>There has been a reinforcement loop in this field. &#8220;We should follow Chris Brogan, he knows what he&#8217;s talking about!&#8221; &#8220;Chris Brogan has 18,000 followers, he must know what he&#8217;s talking about!&#8221;</p>
<p>&#8220;I&#8217;ll subscribe to Problogger because they&#8217;ll help me get more subscribers. They must be good, look how many subscribers they have!&#8221;</p>
<p>Now there is finally an opportunity to put all this theory into practice. Can you use Chris Brogan&#8217;s advice to build relationships on Twitter with people who aren&#8217;t already excited about building relationships on Twitter? Can you use Darren Rowse&#8217;s advice to build an audience of people who aren&#8217;t other bloggers?</p>
<p>If I could sit down with Chris Brogan and Laura Fitton and Darren Rowse <em>now</em>, I wouldn&#8217;t be asking &#8220;who is the audience.&#8221; I would just say &#8220;Ok, the audience is here. Now show me.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/social-media-marketing-this-is-your-chance-215/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript: Private Static Members, Part 1</title>
		<link>http://coffeeonthekeyboard.com/javascript-private-static-members-part-1-208/</link>
		<comments>http://coffeeonthekeyboard.com/javascript-private-static-members-part-1-208/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 14:47:54 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=208</guid>
		<description><![CDATA[A little while ago I talked about creating private variables and methods in JavaScript. This works, but is not necessarily efficient: each instance of the class creates new copies of the members. While that may be exactly what you want for instance variables (think of partNum in the old examples) it is not always ideal.
The [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://coffeeonthekeyboard.com/private-variables-in-javascript-177/" title="A little while ago">A little while ago</a> I talked about creating private variables and methods in JavaScript. This works, but is not necessarily efficient: each instance of the class creates new copies of the members. While that may be exactly what you want for instance variables (think of <code>partNum</code> in the old examples) it is not always ideal.</p>
<p>The complexity jumps significantly, though. So I&#8217;m dividing this half into two parts.</p>
<p>To get started, we need to forget about all this Object-Oriented Programming for a minute and look at some of the neat <a href="http://coffeeonthekeyboard.com/firefox-open-in-blank-tab-197/" title="tricks">tricks</a> you can do with functions in JavaScript.</p>
<p><strong>Update:</strong> <a href="http://coffeeonthekeyboard.com/javascript-private-static-members-part-2-218/" title="Part 2">Part 2</a> is now available.<span id="more-208"></span></p>
<p>First, let&#8217;s take a look at a few ways to define a function in JavaScript:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">function</span> oneFunction <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// function body goes here</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">var</span> anotherFunction = <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// function body goes here</span><br />
<span class="br0">&#125;</span>;</div>
<p>The first example, <code>oneFunction</code> should be familiar to programmers from most languages. The second one is completely equivalent, but works slightly differently. In this case, the right-hand side, a function, is being assigned to the left-hand side, the var <code>anotherFunction</code>.</p>
<p>Remember that in JavaScript, functions are first-class objects, just like everything else, so can be declared with the <code>var</code> keyword. They can also be passed to other functions as arguments, or returned from functions.</p>
<p>Now let&#8217;s take a brief look at parentheses. What do parentheses really do? Essentially, they evaluate and return whatever expression is inside them. For example:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> five = <span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span>;<br />
<span class="co1">// the expression is &quot;5&quot;</span></p>
<p><span class="kw2">var</span> nine = <span class="br0">&#40;</span><span class="nu0">2</span> * <span class="nu0">4</span><span class="br0">&#41;</span> + <span class="nu0">1</span>;<br />
<span class="co1">// &quot;2 * 4&quot; is evaluated and returned as &quot;8&quot;</span></p>
<p><span class="kw2">var</span> nottrue = <span class="br0">&#40;</span><span class="kw2">true</span> || <span class="kw2">false</span><span class="br0">&#41;</span> &amp;amp;&amp;amp; <span class="kw2">false</span>;<br />
<span class="co1">// &quot;true || false&quot; evalutes to &quot;true&quot;</span></p>
<p><span class="kw2">var</span> thirty = <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="nu0">5</span>*<span class="nu0">5</span><span class="br0">&#41;</span><span class="nu0">-10</span><span class="br0">&#41;</span>*<span class="nu0">2</span>;<br />
<span class="co1">// &quot;5*5&quot; is evaluated, then returned as 25 to 25-10,</span><br />
<span class="co1">// which evaluates to 15, which is returned and doubled</span></div>
<p>So parentheses are slightly more powerful than the simple grouping operation we associate with them. Sometimes we see examples like this, which may be more illustrative:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">function</span> checkName <span class="br0">&#40;</span><span class="kw3">name</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw3">name</span>==<span class="st0">&#8216;admin&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
<p>So what happens if we combine parentheses&#8217; ability to evaluate and return code with our ability to define functions as an expression?</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> aFunc = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="coMULTI">/*&#8230;*/</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
<p>Of course, this is just the same as <code>anotherFunction</code> above, but you can see that the right-hand side &#8220;returns&#8221; a function. Let&#8217;s do something a little different now:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="kw3">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Hello, &quot;</span>+<span class="kw3">name</span>+<span class="st0">&quot;!&quot;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="st0">&quot;World&quot;</span><span class="br0">&#41;</span>;</div>
<p>What&#8217;s going on here? The first set of parentheses [<code>(function ... )</code>] evaluate and return the code inside, creating a function. The last set [<code>("World")</code>] are then <em>calling</em> the function created by the first set. Immediately.</p>
<p>This is a powerful technique, but has certain limits. The interior function is executed immediately on creation, which means the <abbr title="Document Object Model">DOM</abbr> will probably not be loaded yet. Once the function is executed, it is lost. Trying to save it in the left-hand side of an equation will only save the <em>return value</em> of the function, not the function itself. For example:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> aFunc = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;I&#8217;m not a function!&quot;</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span>aFunc<span class="br0">&#41;</span>; <span class="co1">// Alerts &quot;I&#8217;m not a function!&quot;</span></div>
<p>But, remember what I said about functions as first-class objects? It means we can use one function as a return value from another function:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> bFunc = <span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1">// 1</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1">// 2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Hello, World!&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// 3</span></div>
<p>The outer function (1) is executed immediately (3), and the var <code>bFunc</code> stores its return value, which is the inner function (2). So now, <code>bFunc</code> is a function, and calling <code>bFunc()</code> will alert &#8220;Hello, World!&#8221;.</p>
<p>We&#8217;ll stop for now. If this technique is new to you, play with it for a while. If not, just hang tight and I&#8217;ll get to <a href="http://coffeeonthekeyboard.com/javascript-private-static-members-part-2-218/" title="Part 2">Part 2</a> soon enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/javascript-private-static-members-part-1-208/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Communities within Communities</title>
		<link>http://coffeeonthekeyboard.com/communities-within-communities-204/</link>
		<comments>http://coffeeonthekeyboard.com/communities-within-communities-204/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 16:38:39 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Social Media]]></category>
		<category><![CDATA[social messaging]]></category>
		<category><![CDATA[Social Networking]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=204</guid>
		<description><![CDATA[There is an op-ed floating around Twitter today: As a social network, Twitter is a dud. Is it ironic that an article deriding Twitter is being spread on Twitter? Irony is so ill-defined.
Twitter is not for everyone, and I respect that, but the author, Alex Groves, seems to be basing his entire point of view [...]]]></description>
			<content:encoded><![CDATA[<p>There is an op-ed floating around Twitter today: <a href="http://www.mcall.com/news/opinion/anotherview/all-point.6868702apr24,0,6909055.story">As a social network, Twitter is a dud</a>. Is it ironic that an article deriding Twitter is being spread on Twitter? Irony is so ill-defined.</p>
<p>Twitter is not for everyone, and I respect that, but the author, Alex Groves, seems to be basing his entire point of view on Ashton Kutcher. Alex claims (and this may well be true; I don&#8217;t know since I&#8217;m never on Facebook) that &#8220;[t]he only problem with all this twittering by celebrities and politicians is that they are on Facebook much more often.&#8221;</p>
<p>Based on this, Alex argues that Twitter is an &#8220;unnecessary&#8221; alternative to Facebook walls and warns that &#8220;[b]y spending more time on social networks and the Internet than we need to, we enable ourselves to become reclusive, sheltered from family and friends.&#8221;</p>
<p>What Alex is ignoring is that most people are not (just) following celebrities. If we look at the number of &#8220;following&#8221; relationships—even relatively inactive people often follow 30 or 40 others—the 1 million &#8220;follows&#8221; of Mr. Kutcher seems much, much less impressive.</p>
<p>What occurs to me, the more I see Twitter on newspaper websites and on the Today show, is that there are multiple communities within a larger community like Twitter.</p>
<p>On the very smallest scale, you may have a &#8220;community&#8221; of family and friends that are mostly following each other. You may have a <a href="http://www.tweetdeck.com/beta/">TweetDeck</a> group set up for them. That kind of mutual relationship leads to what Clive Thompson of the Times called &#8220;<a href="http://www.nytimes.com/2008/09/07/magazine/07awareness-t.html?_r=1">ambient awareness</a>&#8220;. I would encourage Alex to read Mr. Thompson&#8217;s article, it might answer his question: &#8220;How does one know if his friends are OK?&#8221;</p>
<p>Now, Alex is absolutely right that spending too much time on the internet can take time away from other meaningful activities, like &#8220;enjoy[ing] a crisp, clean-smelling spring morning.&#8221; (With my allergies, I don&#8217;t think I have ever &#8220;enjoy[ed]&#8221; that.)</p>
<p>But the same could be said about almost any aspect of life. Too much time at work causes you to lose time with the family. Too much time away from work can make you lose your job. Too much time using computers can give you carpal tunnel.</p>
<p>On the large end of communities, I think you could classify several, such as &#8220;people interested in social networking,&#8221; &#8220;people interested in marketing,&#8221; &#8220;people interested in programming&#8221; (I&#8217;m in all three of these communities) &#8220;people interested in celebrities,&#8221; &#8220;people interested in news,&#8221; &#8220;people interested in &lt;insert your special topic here&gt;.&#8221;</p>
<p>I would argue that these communities reflect real-life relationships the same way the small communities do. A person who is more likely to read Us Weekly is probably more likely to follow more celebrities. A person who enjoys Britney Spears&#8217; music is more likely to follow her. Just as I am more likely to make a joke about the word &#8220;const&#8221; on a construction sign, I am more likely to follow <a href="http://twitter.com/jeresig">John Resig</a>.</p>
<p>Alex asks, &#8220;[w]ith all the good we can do online, including disseminating information and spreading knowledge, why do we become obsessed with Britney Spears tweeting about playing with the boys on tour?&#8221;</p>
<p>I contend that the people Alex is really criticizing (surely many of the <a href="http://www.techcrunch.com/2009/04/24/twitter-eats-world-global-visitors-shoot-up-to-19-million/">newest users</a>) are the same people snapping up People at the checkout lane and watching TMZ in the mornings. Furthermore, he fails to recognize the rather large community of users that uses Twitter to share information and resources, follow the lives of people who may be emotionally, but not physically close, or generate other types of value.</p>
<p>The complaints he levies could—arguably <em>should—</em>be equally directed at Facebook, MySpace, several websites, magazines and TV shows. Alex is confusing &#8220;Twitter&#8221; with a culture of &#8220;celebrity worship.&#8221;</p>
<p>I argue that the people creating value off Twitter (and Facebook) are the same people creating it <em>on</em> Twitter. If all you follow on Twitter are celebrities, you obviously aren&#8217;t contributing much to that community&#8217;s conversation. On the other hand, if your community is broad, and includes peers, friends, family, then you have a unique opportunity to both benefit from, and provide benefit to, that community.</p>
<p>Fortunately, the way Twitter works, I don&#8217;t need to follow those celebrities. And neither do you, Alex.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/communities-within-communities-204/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Firefox: Open in Blank Tab</title>
		<link>http://coffeeonthekeyboard.com/firefox-open-in-blank-tab-197/</link>
		<comments>http://coffeeonthekeyboard.com/firefox-open-in-blank-tab-197/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 14:47:41 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=197</guid>
		<description><![CDATA[If you don&#8217;t use Firefox 3, go get it. Then finish this article. (Safari and Opera users are excused, but there&#8217;s no promise this will work for them.)
One of my (few) gripes with Firefox is that bookmarks on the toolbar have no &#8220;open in blank tab&#8221; option. They have an &#8220;open in sidebar&#8221; option, but [...]]]></description>
			<content:encoded><![CDATA[<p>If you don&#8217;t use Firefox 3, <a href="http://www.mozilla.com/en-US/">go get it</a>. Then finish this article. (Safari and Opera users are excused, but there&#8217;s no promise this will work for them.)</p>
<p>One of my (few) gripes with Firefox is that bookmarks on the toolbar have no &#8220;open in blank tab&#8221; option. They have an &#8220;open in sidebar&#8221; option, but those uses are rare and esoteric at best. Personally, I never use the sidebar.</p>
<p>&#8220;Open in blank tab&#8221; should basically do this: if there is a blank tab, use it; if not, create a new tab. Frankly, it could just open in a new tab regardless, but it seems like such an easy thing to add.</p>
<p>But? It can&#8217;t be done directly in Firefox. Hence, I present this small script:</p>
<div class="dean_ch" style="white-space: wrap;">javascript:<br />
<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw2">var</span> u=<span class="st0">&#8216;http://mail.google.com/mail&#8217;</span>;<br />
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>window.<span class="me1">location</span>==<span class="st0">&#8216;about:blank&#8217;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; window.<span class="me1">location</span>=u;<br />
&nbsp; <span class="br0">&#125;</span><span class="kw1">else</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; window.<span class="kw3">open</span><span class="br0">&#40;</span>u,<span class="st0">&#8221;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p>That&#8217;s it. Try dragging this link to <a href="javascript:(function(){var%20u='http://mail.google.com/mail';%20if(window.location=='about:blank'){window.location=u;}else{window.open(u,'');}})();">GMail</a> to your bookmark toolbar. Then click the link on your toolbar. Now, open a new tab, and click the link again.</p>
<p>This isn&#8217;t exactly what I asked for. It has no way of knowing if any blank tab exists, only if the current tab is blank. And, of course, it lacks the nice favicon support.</p>
<p>But it does the job. If you change the variable <code>u</code> to something other than &#8216;http://mail.google.com/mail&#8217;, you can make the link open any other page.</p>
<p>I love anonymous functions.</p>
<p><strong>Update:</strong> If you want a bookmark for something besides GMail, you can <a href="javascript:(function(){var u=prompt('Enter the URL to open in a blank tab.','http://');prompt('Copy the text below into a new bookmark.',&quot;javascript:(function(){var u='&quot;+u+&quot;';if(window.location=='about:blank'){window.location=u;}else{window.open(u,'');}})();&quot;);})();">create your own</a>. Or you can drag <em>this</em> link to your toolbar, to make new ones whenever you want: <a href="javascript:(function(){var u=prompt('Enter the URL to open in a blank tab.',window.location);prompt('Copy the text below into a new bookmark.',&quot;javascript:(function(){var u='&quot;+u+&quot;';if(window.location=='about:blank'){window.location=u;}else{window.open(u,'');}})();&quot;);})();">Open in Blank Tab</a>.</p>
<p><strong>Update 2:</strong> Oops, fixed the &#8220;create your own&#8221; link. Tested it, then accidentally pasted in the results, instead of the actual script.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/firefox-open-in-blank-tab-197/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Twitter Turn-Around</title>
		<link>http://coffeeonthekeyboard.com/a-twitter-turn-around-195/</link>
		<comments>http://coffeeonthekeyboard.com/a-twitter-turn-around-195/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 13:24:40 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[citypulse]]></category>
		<category><![CDATA[retraction]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=195</guid>
		<description><![CDATA[A little while ago, I criticized a local newspaper, Lansing CityPULSE, for their use of Twitter. They were following the spammer model: follow hundreds of people, then post nothing but links to your own site.
I&#8217;m happy to say—though I&#8217;m a bit late in saying it—that @CityPULSE has really turned around and started making great use [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://coffeeonthekeyboard.com/oh-the-humanity-of-twitter-155/" title="little while ago">little while ago</a>, I criticized a local newspaper, Lansing <a href="http://www.lansingcitypulse.com/lansing/">CityPULSE</a>, for their use of Twitter. They were following the spammer model: follow hundreds of people, then post nothing but links to your own site.</p>
<p>I&#8217;m happy to say—though I&#8217;m a bit late in saying it—that @<a href="http://twitter.com/CityPULSE">CityPULSE</a> has really turned around and started making great use of Twitter.</p>
<p>They&#8217;ve been interacting with the community, been very restrained in how often they link their own site, and been sounding much more human. They could share more good links, but then, so could I.</p>
<p>The best thing @<a href="http://twitter.com/CityPULSE">CityPULSE</a> has been doing is using Twitter to live blog the <a href="http://twitter.com/CityPulse/status/1442006038">Lansing City Council meetings</a>. This is a great way for a local, weekly paper to do up-to-the-minute news. My only suggestion: hash tags so we can find all your council meetings tweets in the search.</p>
<p>Keep up the good work, @<a href="http://twitter.com/CityPULSE">CityPULSE</a>. And if you&#8217;re from the greater Lansing area, or a smaller newspaper, give them a follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/a-twitter-turn-around-195/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Private Variables in JavaScript</title>
		<link>http://coffeeonthekeyboard.com/private-variables-in-javascript-177/</link>
		<comments>http://coffeeonthekeyboard.com/private-variables-in-javascript-177/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 03:28:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[client-side]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[objects]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://coffeeonthekeyboard.com/?p=177</guid>
		<description><![CDATA[Ok, enough of this social/ranting stuff. Time to write something vaguely technical.
I have a love-hate relationship with JavaScript. I think anyone who works with it does. Sometimes it just doesn&#8217;t do what you expect, and it&#8217;s certainly different.
One trick, especially for people from real Object-Oriented languages like Java, Ruby, or let&#8217;s even say PHP 5, [...]]]></description>
			<content:encoded><![CDATA[<p class="note">Ok, enough of this social/ranting stuff. Time to write something vaguely technical.</p>
<p>I have a love-hate relationship with <a href="http://www.quirksmode.org/dom/compatibility.html">JavaScript</a>. I think anyone who works with it does. Sometimes it just doesn&#8217;t do what you expect, and it&#8217;s certainly different.</p>
<p>One trick, especially for people from real Object-Oriented languages like Java, Ruby, or let&#8217;s even say PHP 5, is the lack of access control. When everything is an object, the inability to hide certain values can become a problem.<span id="more-177"></span></p>
<p>Say, for example, you create an object that represents a product you sell, and you want to use one of your part numbers to identify the object. Let&#8217;s say the format for your part number is 1234-56. You might do something like&#8230;</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">function</span> Product <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">partNum</span>;<br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">setPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span> num <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> partNumRegex.<span class="me1">match</span><span class="br0">&#40;</span>num<span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">partNum</span> = num;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>You&#8217;re expecting the rest of your team to be respectful and use the <code>Product.setPartNum()</code> method, which should stop them from using an illegally formatted part number. (<code>partNumRegex</code> is left as an exercise to the reader.)</p>
<p>But what&#8217;s stopping them from doing this?</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> jacket = <span class="kw2">new</span> Product;<br />
jacket.<span class="me1">partNum</span> = <span class="st0">&#8216;1234&#8242;</span>;</div>
<p>Now when they call your Ajax-driven <code>getProductData()</code> method, they&#8217;ll get an error. Had they used the <code>setPartNum()</code> method, they would&#8217;ve seen the error much earlier.</p>
<p>One trick to JavaScript is that variables are <a href="http://en.wikipedia.org/wiki/Scope_(programming)#Static_scoping_.28also_known_as_lexical_scoping.29">lexically scoped</a>. Basically, functions use the value of a variable where they are defined, not where they&#8217;re executed, for example (or just read <a href="http://blogs.msdn.com/kartikb/archive/2009/01/15/lexical-scoping.aspx">a better article</a>):</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">var</span> a = <span class="nu0">1</span>;</p>
<p><span class="kw2">function</span> globalA<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span>; <span class="co1">//1</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">function</span> localA <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> a = <span class="nu0">2</span>;<br />
&nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span>; <span class="co1">//2</span><br />
<span class="br0">&#125;</span></div>
<p>So how does this help? Well, you can effectively hide values in a deeper scope. Instead of using the <code>this</code> keyword, just define new variables within your function:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">function</span> Product <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNum;<br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">setPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span>num<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Fancy checking logic</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">getPartNum</span> = <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> partNum;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">var</span> tshirt = <span class="kw2">new</span> Product;<br />
tshirt.<span class="me1">partNum</span> = <span class="nu0">7</span>;<br />
tshirt.<span class="me1">getPartNum</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// null</span></div>
<p>This same thing can apply to private methods. Don&#8217;t want the new guy calling <code>superSecretInternalMethod()</code>? One common practice is to start private methods with an underscore, but a better way is to actually hide the method:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">function</span> Product<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> partNum; <span class="co1">// private part number, use accessors</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">setPartNum</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// as above</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">getPartNum</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> partNum;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw2">function</span> superSecretInternalMethod<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Whatever your coding-ninja heart desires</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// I can access partNum</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">var</span> truck = <span class="kw2">new</span> Product;<br />
truck.<span class="me1">superSecretInternalMethod</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// JS Error: truck.superSecretInternalMethod is not a function.</span></div>
<p>We can even go a step farther and define private class methods and variables, but this post is already long enough, and it&#8217;s rare I have material for two in a row, so I&#8217;ll save that for next time.</p>
<p class="note">If you haven&#8217;t read it, go get <a href="http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X">Pro JavaScript Design Patterns</a>. You won&#8217;t regret it.</p>
]]></content:encoded>
			<wfw:commentRss>http://coffeeonthekeyboard.com/private-variables-in-javascript-177/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
