<?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>Mixu&#039;s blog</title>
	<atom:link href="http://blog.mixu.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mixu.net</link>
	<description>When I read what I write I learn what I think.</description>
	<lastBuildDate>Wed, 24 Feb 2010 14:24:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Options for securing PHP in a shared virtual hosting environment</title>
		<link>http://blog.mixu.net/2010/02/options-for-securing-php-in-a-shared-virtual-hosting-environment/</link>
		<comments>http://blog.mixu.net/2010/02/options-for-securing-php-in-a-shared-virtual-hosting-environment/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 22:23:39 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=742</guid>
		<description><![CDATA[The terms and options for implementing security measures can be quite confusing. This blog post is a survey of the options available, including some possible pros and cons and definitions of relevant terminology.
It is very typical to run multiple sites on a single server, since it would be overkill to run each small website and [...]]]></description>
			<content:encoded><![CDATA[<p>The terms and options for implementing security measures can be quite confusing. This blog post is a survey of the options available, including some possible pros and cons and definitions of relevant terminology.</p>
<p>It is very typical to run multiple sites on a single server, since it would be overkill to run each small website and blog on its own VPS instance. The default Apache setup: mod_php and prefork-mpm does not offer any privilege separation or hardening for virtual hosts. Hence the need for additional security measures.</p>
<p><strong>What are the general approaches taken to securing PHP?</strong></p>
<p>The approaches taken in securing PHP can be divided into two broad categories:</p>
<ol>
<li><strong>Hardening PHP</strong>. This approach aims to improve the security of PHP scripts by limiting dangerous functionality on a site-by-site basis and by preventing flaws from escalating through additional patches to the PHP core. The main examples are: a) tweaking PHP core settings such as open_basedir and b) running a version of PHP which includes additional options to limit functionality and prevent flaws such as buffer overflows (<a href="http://www.hardened-php.net/suhosin/">Suhosin</a>).</li>
<li><strong>Privilege separation. </strong>This approach limits the extent to which other sites can be damaged if one of the websites on the shared server is compromised. There are several solutions, including <a href="http://www.suphp.org/">mod_suPHP</a> and <a href="http://httpd.apache.org/docs/2.0/suexec.html">suEXEC</a>.</li>
</ol>
<p><strong>How can PHP and Apache interact?</strong></p>
<p>There are several ways in which PHP and other scripts can be invoked by Apache:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI (Common Gateway Interface) </a>is a standard protocol that defines how webserver software can delegate the generation of webpages to a console application. It operates on a &#8220;one new process per request&#8221; basis.</li>
<li><a href="http://en.wikipedia.org/wiki/FastCGI">FastCGI</a> is a protocol introduced in the mid-1990s that improves upon the older CGI protocol. It allows a single persistent process pool to handle multiple requests over its lifetime, reducing overhead.</li>
<li>In-process as an Apache module, such as the default mod_php.</li>
</ul>
<p>The default interaction between PHP and Apache is handled by the mod_php module. The most common ways of implementing privilege separation use either CGI or FastCGI to interface with PHP. PHP supports both CGI and FastCGI protocols.</p>
<p><strong>Privilege separation can be done either:</strong></p>
<ol>
<li>by using CGI scripts and suEXEC, a feature built in Apache</li>
<li>by using Apache modules that make invoking CGI scripts easier
<ul>
<li><em>Apache modules</em> are bundles that can be loaded to add new functionality to Apache. They are integrated into the Apache server and add new functionality to instances of the server, such as the capability to interpret PHP scripts.</li>
</ul>
<ul>
<li>Examples: mod_php, mod_suPHP, mod_fastcgi and mod_fcgid.</li>
</ul>
</li>
<li>by using Apache MPMs that support privilege separation
<ul>
<li><a href="http://httpd.apache.org/docs/2.0/mpm.html"><em>Apache MPMs</em></a><em> (Multi-Processing Modules)</em> are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests. There are several different MPMs &#8211; the Unix platform default is the prefork mpm.</li>
<li>Examples: prefork, worker, perchild, mpm_itk, mpm_peruser</li>
</ul>
</li>
</ol>
<p><strong>What are the options for privilege separation?</strong></p>
<p><strong>suEXEC</strong></p>
<p><strong><span style="font-weight: normal;">suEXEC is a feature built into Apache, but not included in the default Apache installation. It makes all CGI scripts execute with the user id and permissions of their owners. It can be used with PHP and with other CGI scripts.</span></strong></p>
<p>It consists of a setuid &#8220;wrapper&#8221; binary that is called by the main Apache web server, and which executes CGI scripts with the correct used id.</p>
<p>+ Tried and tested</p>
<p>+ Can be used with other languages than PHP</p>
<p>- Low performance without FastCGI (similar to suPHP)</p>
<p>- Separate script files are a minor hassle</p>
<p><strong>Module: mod_suPHP </strong></p>
<p>mod_suPHP makes PHP scripts execute with the user id and permissions of their owners.</p>
<p>It consists of an Apache module (mod_suphp) and a setuid root binary (suphp), which calls PHP as a CGI process.</p>
<p>+ Easy to install, in RPMForge repo (http://wiki.centos.org/AdditionalResources/Repositories/RPMForge)</p>
<p>+ Quite commonly used</p>
<p>- Low performance relative to others (similar to suEXEC)</p>
<p>- PHP specific solution</p>
<p>= Recommended for low load sites which are not using their resources to their limits.</p>
<p><strong>Module: FastCGI (mod_fastcgi or mod_fcgid)</strong></p>
<p>mod_fastcgi and mod_fcgid implement process persistence between page views and communicate with PHP using FastCGI. They do not by themselves perform privilege separation, suEXEC is needed.</p>
<p>+ Decent performance when using suEXEC with FastCGI, similar or better performance than mod_php has been reported</p>
<p>+ Can be used with other languages than PHP</p>
<p>- FastCGI may require more memory because there are more persistent processes (more suited for servers with a lot of memory)</p>
<p>- Separate script files are a minor hassle</p>
<p>= Recommended for higher load sites.</p>
<p><strong>MPM: mpm_itk and mpm_peruser</strong></p>
<p>These are alternative MPMs for Apache that replace the default preform MPM and perform additional privilege separation.</p>
<p>mpm_itk works in a manner similar to regular CGI scripts in that it does not reuse processes after each request. However, unlike CGI scripts, it invokes each process with the user id and group specified for that virtual host.</p>
<p>+ Neat solution with decent performance, some systems have it in the repos</p>
<p>- Must patch and compile separately in Centos</p>
<p>- Not as commonly used as suEXEC or suPHP</p>
<p>= Recommended as a upcoming solution that is higher performance than mod_suPHP and easier to setup than suEXEC+FastCgi.</p>
<p>mpm_peruser creates one or more apache child processes for each unique user/group, each handling its own set of virtual hosts.</p>
<p>+ Faster than mpm_itk</p>
<p>- Must patch and compile separately in most systems</p>
<p>- Development and adoption seems to be more limited than mpm_itk</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2010/02/options-for-securing-php-in-a-shared-virtual-hosting-environment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>10-month retrospective on writing this blog</title>
		<link>http://blog.mixu.net/2010/01/10-month-retrospective-on-writing-this-blog/</link>
		<comments>http://blog.mixu.net/2010/01/10-month-retrospective-on-writing-this-blog/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 12:19:52 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Meta]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=648</guid>
		<description><![CDATA[I started writing this blog on a whim ten months ago. Here is quick look back at my three original goals and things I have learned.
1. To write about things you care about for yourself
Have I succeeded? Yes. This is probably the goal I am most satisfied with. I find myself referring back to my [...]]]></description>
			<content:encoded><![CDATA[<p>I started writing this blog on a whim ten months ago. Here is quick look back at my three original goals and things I have learned.</p>
<h3><strong>1. To write about things you care about for yourself</strong></h3>
<p><em>Have I succeeded?</em> Yes. This is probably the goal I am most satisfied with. I find myself referring back to my own posts (e.x. on <a href="http://blog.mixu.net/2009/11/setting-up-spf-senderid-and-dkim-on-centos-5-3-using-sendmail/">how to setup DKIM on Centos</a>, or <a href="http://blog.mixu.net/2009/08/semantic-css-naming-best-practices/">how to implement semantic naming in CSS</a>), which I think is an indication that what I write has longer-lasting value to me.</p>
<p><strong>Lesson learned #1:</strong> Writing helps you clarify your own thoughts. To me, this not an online diary &#8211; my blog is my online whiteboard.</p>
<p><strong>Lesson #2: </strong>Writing a blog helps you with expressing your ideas briefly.<strong> </strong>Writing a blog has been educational, because one needs to really stick to simple, short and easy-to-skim posts. My point of comparison is academic writing, which is much more rigorous with the details and definitions of concepts. With blog posts, you can&#8217;t do that because of space limitations.</p>
<p><strong>Lesson #3:</strong> The best test for content you write in my opinion is whether you would give a damn if someone else wrote about this very same topic. Another good question is whether you think you will give a damn in a week, a month or a year? Not all content is evergreen, but I do think it should either be something worth revisiting/updating later; or if that is not possible at least timely and helpful.</p>
<p><strong><strong>2. To learn about marketing and publicity without having to face high stakes</strong></strong></p>
<p><em>Have I succeeded?</em>Not really. Writing a blog has kept the thought of marketing it in the back of my mind, but so far I have done very little about it.</p>
<p><strong>Lesson #3: </strong> Headlines and searchability matters. As of now, I have about 2000 monthly visitors, or 60-70 per day. Most of that traffic comes from Google searches on the relevant topic. The posts that get no traffic are those that have a title that no-one searches for.</p>
<p><strong>Lesson #4:</strong> Blogging is about taking part in a conversation with other people. If you want traffic, you need to interact with other blogs and contribute. Search engines can only give you the traffic that cares about that specific topic, long-term engagement seems to be a result of building connections and referrals.</p>
<p><strong>Lesson #5:</strong> A blog is an extension what you do offline. No point in getting obsessed with getting referred to online if you do not connect to people in the real world. I&#8217;d prefer my blog to be a convenient way of learning more about me and the topics I discuss off the Internet rather than a separate endeavor.</p>
<p><strong>3. Realize that the rest of the world does not, in fact, give a damn </strong></p>
<p><span style="font-weight: normal;"><em>Have I succeeded?</em> Yes. Woohoo! Nobody cares, and I don&#8217;t give a damn. As <a href="http://sivers.org/up2you">Derek Sivers said</a>, <em>&#8220;Nobody&#8217;s going to help you. Does that encourage you or discourage you?&#8221;</em> </span></p>
<p><span style="font-weight: normal;"><strong>Lesson #6:</strong></span><span style="font-weight: normal;"> In my opinion, if something is worth doing, it&#8217;s worth doing whether or not other people give a damn. </span></p>
<p><span style="font-weight: normal;">One of my favorite recent quotes is from <a href="http://en.wikipedia.org/wiki/James_Stockdale">James Stockdale</a>, a Vietnam POW: <em>&#8220;You must never confuse faith that you will prevail in the end—which you can never afford to lose—with the discipline to confront the most brutal facts of your current reality, whatever they might be.&#8221;</em> That nobody cares is a reality, and if that makes you feel like crying, you might as well not try.</span></p>
<p><span style="font-weight: normal;"><strong>What will 2010 look like?</strong></span></p>
<h3><span style="font-weight: normal; font-size: 13px;">What I will NOT do:</span></h3>
<div>
<ol>
<li>Blog more frequently. This is not my third or fourth job. It&#8217;s a hobby. A couple of posts a month is just fine, as long as they are quality posts or solve some real problem.</li>
<li>Link trading, link fishing, directory listings, forum participation. It may work, but I don&#8217;t care enough to start some sort of campaign solely for the sake of getting more traffic. I will link to things I refer to and would like to be a bit more active in commenting about stuff I care about, however.</li>
<li>Advertising, either on the blog or for the blog. I don&#8217;t need the money and I will certainly not pay for some #¤%&amp;?! to visit my blog.</li>
</ol>
</div>
<div>What I will do:</div>
<div>
<ol>
<li>Respond to commenters (more).</li>
<li>Be a bit more active with commenting on other blogs. I haven&#8217;t done this so far, because I just don&#8217;t have the habit of writing comments. However, since I like getting comments on my posts, it would probably be nice to do the same &#8211; but only if I have a real opinion or alternative viewpoint.</li>
<li>Cross-promote posts on your own blog. It&#8217;s not enough to be useful, you also need to make other relevant content easy to find on your blog.<br />
I am surprised at how bad most blogs are with making me click on a second post if I liked the one I read. Archives need to list all the posts simply, most popular content helps understand what the blog is about, and then there should be &#8220;collection pages&#8221; that collect and summarize previous posts on relevant topics. Related posts and updates (e.g. to link to a relevant later post) are also important.  Gotta still write those collection pages for this blog.</li>
<li>Create positive expectations regarding future content. It is the expectation that future posts are good that makes me interested in a blog.<br />
Creating a series of posts on a topic, or by highlighting other resources or ongoing projects will probably help build positive expectations for this blog.</li>
<li>Make it easier to share stuff and subscribe via RSS. This probably means adding those widgets for sharing a post, adding a free feed-sharing service, better RSS links and perhaps Twitter reactions (if I ever start using Twitter).</li>
<li>Guest author on some other blog or have another blogger guest post/interview here.</li>
<li>Look at the CSS of this site to make the text easier to skim.</li>
<li>Add downloadable stuff. Since I already writing about code, why not publish some and make those downloads easily accessible? Since I am already writing scientific articles and working papers, why not make those available?</li>
</ol>
</div>
<div><strong>Recommended stuff</strong></div>
<div><strong><br />
</strong></div>
<div><a href="http://www.problogger.net/archives/2008/03/11/how-id-promote-my-blog-if-i-were-starting-out-again/">http://www.problogger.net/archives/2008/03/11/how-id-promote-my-blog-if-i-were-starting-out-again/</a></div>
<div><a href="http://www.problogger.net/archives/2005/08/17/converting-one-off-visitors-to-your-blog-into-regular-readers/">http://www.problogger.net/archives/2005/08/17/converting-one-off-visitors-to-your-blog-into-regular-readers/</a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2010/01/10-month-retrospective-on-writing-this-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finnish translation for Subscribe2 / Suomenkielinen käännös Subscribe2 -pluginiin</title>
		<link>http://blog.mixu.net/2010/01/finnish-translation-for-subscribe2-suomenkielinen-kaannos-subscribe2-pluginiin/</link>
		<comments>http://blog.mixu.net/2010/01/finnish-translation-for-subscribe2-suomenkielinen-kaannos-subscribe2-pluginiin/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 22:19:15 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=709</guid>
		<description><![CDATA[Installation instructions
I&#8217;ve made a Finnish translation for the Wordpress Subscribe2 -plugin, download it here: subscribe2-fi.zip
Upload the subscribe2-fi.mo file to the wp-content/plugins/subscribe2/ directory. If WPLANG in wp-config.php is something other than the default &#8220;fi&#8221;, then change &#8220;fi&#8221; in the filename to the correct value.
I was reminded again how hard it is do proper translations in Finnish because of [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Installation instructions</strong></p>
<p>I&#8217;ve made a Finnish translation for the Wordpress Subscribe2 -plugin, download it here: <a href="http://blog.mixu.net/wp-content/uploads/2010/01/subscribe2-fi.zip">subscribe2-fi.zip</a></p>
<p>Upload the subscribe2-fi.mo file to the wp-content/plugins/subscribe2/ directory. If WPLANG in wp-config.php is something other than the default &#8220;fi&#8221;, then change &#8220;fi&#8221; in the filename to the correct value.</p>
<p>I was reminded again how hard it is do proper translations in Finnish because of the differences in word order compared to English, e.g. &#8220;For digest notifications, date order for posts is&#8221; -&gt; &#8220;Yhteenvetomuotoisissa päivityksissä artikkelien (aika)järjestys on&#8221;&#8230;</p>
<p>If you want to improve the translation, open the .po -file in Poedit or some other editor. The translation was done in one go, so I some of the wordings could be improved. (Then again, the terminology in the Finnish Wordpress itself is sometimes rather confusing.)</p>
<p><span id="more-709"></span></p>
<p><strong>Asennusohjeet</strong></p>
<p>Tein suomenkielisen käännöksen Wordpressin Subscribe2 -pluginiin, lataa se tästä: <a href="http://blog.mixu.net/wp-content/uploads/2010/01/subscribe2-fi.zip">subscribe2-fi.zip</a></p>
<p>Lataa tiedosto subscribe2-fi.mo kansioon wp-content/plugins/subscribe2/. Jos WPLANG -kohta wp-config.php -tiedostossa ei ole &#8220;fi&#8221; (oletusarvo suomenkielisessä Wordpressissä), muuta &#8220;fi&#8221; tiedostonnimessä oikeaan arvoon eli WPLANG:in mukaiseksi.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2010/01/finnish-translation-for-subscribe2-suomenkielinen-kaannos-subscribe2-pluginiin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Organizing Javascript code</title>
		<link>http://blog.mixu.net/2010/01/organizing-javascript-code/</link>
		<comments>http://blog.mixu.net/2010/01/organizing-javascript-code/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 14:43:06 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=607</guid>
		<description><![CDATA[Javascript is an interesting language because it is flexible and surprisingly powerful. Once you grow up from having one static page into having a large number of pages in a dynamic web application, you need conventions on how to organize your code.
In my opinion, there are two parts to the problem:

the easy part, which is [...]]]></description>
			<content:encoded><![CDATA[<p>Javascript is an interesting language because it is flexible and surprisingly powerful. Once you grow up from having one static page into having a large number of pages in a dynamic web application, you need conventions on how to organize your code.</p>
<p>In my opinion, there are two parts to the problem:</p>
<ol>
<li>the easy part, which is to apply JS programming patterns</li>
<li>the hard part, which is doing so in a consistent and maintainable manner</li>
</ol>
<h3>The easy part: Namespaces, modules and commenting conventions</h3>
<p><strong>Namespace and module pattern</strong></p>
<p>Javascript has no explicit syntax for advanced language features such as namespaces and private variables, but these can be implemented using very simple programming patterns.</p>
<p>A lot has been written on the namespace and module pattern, so I will only illustrate it here.</p>
<p>I like to add a &#8220;placeholder&#8221; function shown below to prevent me from making errors while modifying the module (<a href="http://blog.mixu.net/2009/05/internet-explorer-and-javascript-code/">IE6 freaks out</a> if there is a comma after the last item). This used to happen when I moved or added the methods and forgot to check whether that the commas are correct.</p>
<p>The example code below is adopted from (<a href="http://yuiblog.com/blog/2007/06/12/module-pattern/">http://yuiblog.com/blog/2007/06/12/module-pattern/</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// create a namespace</span>
YAHOO.<span style="color: #003366; font-weight: bold;">namespace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myProject&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Assign the return value of an anonymous function to the namespace</span>
<span style="color: #009966; font-style: italic;">/** @namespace */</span>
YAHOO.<span style="color: #660066;">myProject</span>.<span style="color: #660066;">myModule</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009966; font-style: italic;">/** @private */</span>
	<span style="color: #003366; font-weight: bold;">var</span> myPrivateVar <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;I can be accessed only from within YAHOO.myProject.myModule.&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009966; font-style: italic;">/** @private */</span>
	<span style="color: #003366; font-weight: bold;">var</span> myPrivateMethod <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		YAHOO.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;I can be accessed only from within YAHOO.myProject.myModule&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009966; font-style: italic;">/** @scope YAHOO.myProject.myModule */</span>
	<span style="color: #000066; font-weight: bold;">return</span>  <span style="color: #009900;">&#123;</span>
		<span style="color: #009966; font-style: italic;">/** describe myPublicProperty here */</span>
		myPublicProperty<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;I'm accessible as YAHOO.myProject.myModule.myPublicProperty.&quot;</span>
		<span style="color: #009966; font-style: italic;">/** describe myPublicMethod here */</span>
		myPublicMethod<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			YAHOO.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;I'm accessible as YAHOO.myProject.myModule.myPublicMethod.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">//Within myProject, I can access &quot;private&quot; vars and methods:</span>
			YAHOO.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>myPrivateVar<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			YAHOO.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>myPrivateMethod<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">//The native scope of myPublicMethod is myProject; we can</span>
			<span style="color: #006600; font-style: italic;">//access public members using &quot;this&quot;:</span>
			YAHOO.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">myPublicProperty</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		<span style="color: #006600; font-style: italic;">/**
		* A placeholder function to prevent errors due to not having a comma after the last function in the return statement for this module.
		*/</span>
		placeholder<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// the parens here cause the anonymous function to execute and return</span></pre></div></div>

<p><strong>Commenting conventions.</strong> Pick a commenting tool and stick with it. Comment the intent of the code and any gotchas as well as the expected arguments and purpose of methods.</p>
<p>The two main JavaScript commenting tools are: <a href="http://code.google.com/p/jsdoc-toolkit/">JsDoc-Toolkit</a> (self-contained Java) and <a href="http://developer.yahoo.com/yui/yuidoc/">YuiDoc</a> (Python).</p>
<p><strong>File names and splitting code into files.</strong> Put all the hard-to-reuse code into its own namespace (ex. Framework. ModuleName. ModulePart.ApplicationName) in a separate file (application.js or custom.js). This way you keep the library clean of any application-specific stuff. It is often hard to avoid implementing some things in a one-off manner, so you might as well organize all the single-use stuff in its own file.</p>
<p>That is, if writing your own extensions to an existing framework, you will most likely have:</p>
<ol>
<li>code that is fully reusable (specialized or pre-configured widgets, utilities etc.)</li>
<li>code that is hard or pointless to reuse (page- or application-specific messages, formatting and utilities)</li>
</ol>
<h3>The hard part: structuring code for reuse, logical naming conventions</h3>
<p><strong>Structuring code for reuse</strong>. Encourage reuse by splitting code into configuration, implementation and customization.</p>
<ol>
<li><strong>Configuration</strong> is anything that might need to change on each instantiation of your widget. It should be single section within a module (a private object in JSON notation). Make sure you have good and documented defaults, because this makes it easier to use the code again.</li>
<li><strong>Implementation </strong> is the main code. It should NEVER contain hardcoded ID&#8217;s, messages or other things that will eventually need to be overridden.</li>
<li><strong>Customization </strong>is a set of page-specific blocks of code that alter the configuration. You only override the few things that are needed for the specific functionality on the page.</li>
</ol>
<p>Here is an example (from <a href="http://www.wait-till-i.com/2008/05/23/script-configuration/">http://www.wait-till-i.com/2008/05/23/script-configuration/</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">myProject.<span style="color: #660066;">myModule</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// CONFIGURATION</span>
  <span style="color: #003366; font-weight: bold;">var</span> config <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    CSS<span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span>
     classes<span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span>
       hover<span style="color: #339933;">:</span><span style="color: #3366CC;">'hover'</span><span style="color: #339933;">,</span>
       active<span style="color: #339933;">:</span><span style="color: #3366CC;">'current'</span><span style="color: #339933;">,</span>
       jsEnabled<span style="color: #339933;">:</span><span style="color: #3366CC;">'js'</span>
     <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
     ids<span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span>
       container<span style="color: #339933;">:</span><span style="color: #3366CC;">'maincontainer'</span>
     <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    timeout<span style="color: #339933;">:</span><span style="color: #CC0000;">2000</span><span style="color: #339933;">,</span>
    userID<span style="color: #339933;">:</span><span style="color: #3366CC;">'chrisheilmann'</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// IMPLEMENTATION</span>
  <span style="color: #003366; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// make init and config public</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
    init<span style="color: #339933;">:</span>init<span style="color: #339933;">,</span>
    config<span style="color: #339933;">:</span>config
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// CUSTOMIZATION</span>
<span style="color: #006600; font-style: italic;">// This makes it possible to override stuff before calling init</span>
module.<span style="color: #660066;">config</span>.<span style="color: #660066;">CSS</span>.<span style="color: #660066;">ids</span>.<span style="color: #660066;">container</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'header'</span><span style="color: #339933;">;</span>
module.<span style="color: #660066;">config</span>.<span style="color: #660066;">userID</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'alanwhite'</span><span style="color: #339933;">;</span>
module.<span style="color: #660066;">init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Naming conventions.</strong> I don&#8217;t mean deciding whether or not to use camelCase, but rather how the logical organization names of variables and widgets should be done. It is reasonably simple to stop using global variables and functions to avoid name conflicts, but what is harder is to come up with a logical naming convention that allows any code to be reused anywhere.</p>
<p>In particular, when you create new widgets, you often need to be able to connect them to one another in some manner. Being able to identifying the type (class) and retrieve/replace data from a new widget using a standard interface takes some planning and a lot of discipline, but it makes reusing the widgets much easier.</p>
<p><strong>ID and name attribute naming convention.</strong> I use &#8220;data[widgetName][recordIndex][fieldName]&#8221; for input names (because PHP will parse this into arrays automatically) and &#8220;widgetName_fieldName_recordIndex&#8221; for ID attributes (because it makes string comparisons easier).</p>
<p><strong>Widget instance naming convention. </strong>I use YAHOO.ApplicationName.WidgetInstanceName for widget instances, and use WidgetInstanceName to create any related tags with IDs.</p>
<p>I am still looking for a good logical naming convention for widgets, but it seems this topic is not as commonly discussed. If you have any tips, please leave a comment!</p>
<p><strong>Reference stuff</strong></p>
<p><a href="http://stackoverflow.com/questions/211795/are-there-any-coding-standards-for-javascript">http://stackoverflow.com/questions/211795/are-there-any-coding-standards-for-javascript</a></p>
<p><a href="http://ajaxian.com/archives/maintainable-javascript-videos-are-now-available">http://ajaxian.com/archives/maintainable-javascript-videos-are-now-available</a></p>
<p><a href="http://yuiblog.com/blog/2007/06/12/module-pattern/">http://yuiblog.com/blog/2007/06/12/module-pattern/</a></p>
<p><a href="http://www.wait-till-i.com/2008/05/23/script-configuration/">http://www.wait-till-i.com/2008/05/23/script-configuration/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2010/01/organizing-javascript-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVC frameworks: stack vs glue, and how to pick the right one</title>
		<link>http://blog.mixu.net/2010/01/mvc-frameworks-stack-vs-glue/</link>
		<comments>http://blog.mixu.net/2010/01/mvc-frameworks-stack-vs-glue/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 13:56:41 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=419</guid>
		<description><![CDATA[MVC, Model-Controller-View, is all the rage in web development these days. With regards to MVC, I think the right question is to ask not whether you should use an MVC framework but rather which framework fits the kinds of problems you are likely to encounter while developing your web application.
MVC frameworks: full stack vs. glue [...]]]></description>
			<content:encoded><![CDATA[<p>MVC, Model-Controller-View, is all the rage in web development these days. With regards to MVC, I think the right question is to ask not whether you should use an MVC framework but rather <em>which framework fits the kinds of problems you are likely to encounter while developing your web application</em>.</p>
<p><strong>MVC frameworks: full stack vs. glue frameworks</strong></p>
<p>There are the two basic options with MVC frameworks: glue frameworks and full stack frameworks.</p>
<ol>
<li>&#8220;Glue frameworks&#8221; are collections of components and libraries which you can use to build an application. Most of the functionality is optional and often you must make decisions regarding how you will structure control flow within your application.</li>
<li>&#8220;Full stack frameworks&#8221; are integrated sets of components in which most of the components and libraries are mandatory and most of the design decisions have been made for you in advance.</li>
</ol>
<p><strong>How full stack frameworks sometimes get in the way: an example</strong></p>
<p>Most frameworks are optimized for the 0-3 month project. All the basic functionality you need is there, but the expectation seems to be that you are creating a custom version of a blog or a CMS and that the most complex bits will be the views (custom code) and the models (posts, users, tags, comments). However, the more you&#8217;re dealing with complexity with regards to business logic, integration, regulatory validation and scaling requirements, the more likely it is that a full-stack framework will require manual optimizations and supplementary mechanisms which are not easily implementable in a full stack framework.</p>
<p>Here is one example of how a full stack framework can end up in more complexity than a glue framework. In CakePHP (a full stack framework), if you want to show multiple &#8220;flash&#8221; messages, you have to rather actively work around the existing mechanism, because it does not support multiple flash messages easily. Yes, you can set one message per action and you can set custom styles, but setting more than one message becomes unnecessarily complex (see <a href="http://bakery.cakephp.org/articles/view/multiple-flashes-with-different-classes">this article and have a look at the comments as well</a>) because by default, the Session flash messages overwrite each other rather than appending to the existing set of messages.</p>
<p>This is a very trivial example &#8211; and you can use the existing Session classes to create most of the functionality necessary to fix this. But if you do that, you will end up with two &#8220;flash&#8221; message functionalities: the default one and the one you built to make it easy to set more than one message of each type.</p>
<p>A glue framework might offer the Session functionality without directly supporting flash messages. This does mean that you have to write your own, but you&#8217;ll end up with a slightly simpler codebase. These kinds of small things add up if you have a larger project.</p>
<p>Now, the key question to me when deciding which to use is:</p>
<p><strong>What kind of complexity/problems are you tackling in your application?</strong></p>
<p>The optimal choice of framework depends on covering the 80% case effectively (without compromising constraints like performance).</p>
<p>Here are some questions to consider when picking the right framework for your project:</p>
<ol>
<li><strong>Complex views &#8211; What are the most probable uses of the system? </strong>Make sure you can cover the technical functionality needed to implement the most important client goals in a way that delights or at least does not annoy your customer. What is key here is the user experience you can deliver, not just technical sophistication.</li>
<li><strong>Complex data structures &#8211; What data structure requirements are most likely to change? </strong>If possible, pick an architecture that makes the most likely changes relatively cheap to make. This may imply a tradeoff of some kind with other functionality.</li>
<li><strong>Complex business logic &#8211; What are the key concepts and processes, and how are these likely to change?</strong> How easy is it to create exceptions to the rule and how can rules be verified and tested?</li>
<li><strong>Complex integration &#8211; What are the key connecting technologies, and how well are they supported by the framework? </strong>Ideally, you can use pre-existing and tested code to integrate key areas.</li>
<li><strong>Strict performance requirements &#8211; What is the everyday workload going to be? </strong>What mechanisms will allow you to identify bottlenecks in the system? Is there a possibility to optimize functionality by scaling horizontally or by bypassing some unnecessary functionality?</li>
<li><strong>Scaling requirements &#8211; How can you partition your workload</strong>? How well do the core mechanisms lend to custom enhancements to fulfill scalability requirements?</li>
<li><strong>Strict schedule requirements &#8211; What is the minimum feature set? </strong>How well does the framework support rapid implementation and testing of the minimum feature set? What are the main dependencies, and are there pre-existing modules or plugins for them?</li>
</ol>
<p>If what you are building is not particularly complex, or the primary complexity is in building the views, then a full-stack framework is likely to be a great choice &#8211; particularly if you are have a very limited schedule. An example of this would be a brochure website, which has most of its complexity in the views.</p>
<p>The larger and more complex the application, the less likely you are to obtain significant productivity gains from using a framework. This is simply because having a framework can at best save you a few hundred hours of work (which should be more than what it would take for you to replicate the functionality you use). If the project is big, the time saved doing this becomes less significant compared to the time needed to build the rest of the application (e.g. the useful parts).</p>
<p><strong><span style="font-weight: normal;"><br />
</span></strong></p>
<p><strong> </strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2010/01/mvc-frameworks-stack-vs-glue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing agile development</title>
		<link>http://blog.mixu.net/2009/12/implementing-agile-development/</link>
		<comments>http://blog.mixu.net/2009/12/implementing-agile-development/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 23:36:32 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=557</guid>
		<description><![CDATA[&#8220;Agile development&#8221; is used to describe a wide variety of development practices. Claiming that one follows an &#8220;agile&#8221; development methodology is easy. But declaring that your practices are &#8220;agile&#8221; is just about as useful as declaring yourself the winner &#8211; saying you are the winner doesn&#8217;t make it so. Thus the question is, how can [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Agile development&#8221; is used to describe a wide variety of development practices. Claiming that one follows an &#8220;agile&#8221; development methodology is easy. But declaring that your practices are &#8220;agile&#8221; is just about as useful as declaring yourself the winner &#8211; saying you are the winner doesn&#8217;t make it so. Thus the question is, how can one ensure that what is called &#8220;agile development&#8221; by some company actually delivers what is expected?</p>
<p>On a surface level I believe it is rather easy to agree with the Agile values. Working in a small company, whether or not the right things are done comes down mostly to a question of self-discipline: there is a number of time-consuming and less exciting things that have a high payoff, but are not done because each person (this includes you, reader) has a preferred way of working. In most cases this good: second-guessing oneself is hardly productive. But in order to actually benefit from best practice one must not only be aware of it but also try to implement it as best possible &#8211; blindingly obvious, but somehow frequently ignored.<strong> </strong></p>
<p>McDonald et al. (2008) make an interesting reference to Auguste Compte&#8217;s Law of Three Stages from 1830. The law proposes that a scientific discipline progresses through three stages: theological (belief-based knowledge), metaphysical (philosophy-based knowledge) and positive (based on scientific reasoning). The authors (each with SW development background of at least 20 years) propose that the Agile movement and manifesto represent a move from belief-based practices towards the second, philosophical stage. This is interesting because it implies that they see Agile (with a big A) is still more as a philosophy than a full methodology &#8211; or more importantly, that doing Agile well requires that you pick and define an overall framework within which you apply the Agile principles.</p>
<p>In a post on his website, Scott Ambler asks <a href="http://www.agilemodeling.com/essays/agileCriteria.htm">five questions to help determine whether a team is Agile</a>:</p>
<ol>
<li>Is the team is doing developer regression testing, or better yet taking a test-driven approach to development?</li>
<li>Are stakeholders active participants in development?</li>
<li>Is the team producing high-quality, working software on a regular basis?</li>
<li>Is the team is working in a highly collaborative, self-organizing manner within an effective governance framework?</li>
<li>Is the team improving their process on a regular basis?</li>
</ol>
<p><strong>Some further questions</strong></p>
<p>I think these are very good questions to identify whether the Agile principles are used in developing software. But if you are thinking about implementing Agile practices, you ought to also be able to answer further questions about the underlying process:</p>
<p>1. What are you doing to detect, predict and prevent defects? &#8220;Regression testing&#8221; is not an answer: what part of your testing is automated? What is the role of practices such code reviews, test scenario development and design validation in your process? Who is responsible for quality assurance and how are defects tracked?</p>
<p>2. How do you manage and communicate requirements? Who talks to the stakeholders? How do you disseminate the information? How do you track fulfilled and unfulfilled requirements? How do requirement changes influence planning and scheduling?</p>
<p>3. How are you ensuring that quality and security concerns are addressed and that lessons learned from previous projects are remembered?</p>
<p>These are just a few process-related questions off the top of my head.</p>
<p><strong>Why can&#8217;t you answer?</strong></p>
<p>If you can&#8217;t answer, or aren&#8217;t doing one or more of these practices, ask why not. My answer to &#8220;why not?&#8221; is that this is a result of a lack of appreciation of whatever the unimplemented best practices could bring, such as: automated testing, active stakeholder participation, better scheduling or controls, self-organization or process improvement accountability. While these are best practices, that does not mean that adopting them is always in the personal interest of the participants of the software development process. For example:</p>
<p>1) Active stakeholder participation may not be valued because it is considered to be customer interference rather than a method of increasing the focus on customer value, or it may not be valued because a consultancy may prefer to have a costly billable change process.</p>
<p>2) Better scheduling or controls may be seen as overhead and micromanagement by developers.</p>
<p>3) Increasing accountability for mistakes may be uncomfortable and thus seen as undesirable.</p>
<p>To me, the key question is how can we can raise the perceived value of these practices in order to create the internal motivation to implement these processes more stringently &#8211; and hence hopefully realize the benefits of best practice in our organization?</p>
<p><strong>Example: TDD</strong></p>
<p>For example, let&#8217;s look at why TDD might not be valued.</p>
<p>Regression testing / test-driven development may not be seen as valuable because of beliefs such as &#8220;the real work of development is implementation&#8221; and &#8220;quality is achieved by molding software into shape by correcting defects&#8221; (McDonald et al. 2008). What could be done to create the internal motivation to implement TDD?</p>
<p>One part would be to examine these beliefs and examine the benefits of defect prevention via TDD. In particular, it may be that the negative impact of the ripple effect of flaws on dependent functionality and the cost in customer satisfaction are underestimated.</p>
<p>Second, there is a larger question of whether quality ought to take precedence over other potential priorities &#8211; because focusing on quality does not mean following best practices only when they are convenient, and throwing them out when the going gets tough. Would you trade intangibles such as quality over tangibles such as lines of codes or number of features or maintaining a release schedule? A quality-oriented organization ought to choose quality over features or schedule and be confident that this will still lead to a better result than prioritizing features or schedule.</p>
<p>Third, there ought to be an increase in emphasis on the test and quality assurance results as a deliverable. Are your test results a deliverable, and do you actually deliver them? Can you make them a deliverable? By making it clear that the results of an intangible activity are still deliverable and are visible work will increase their perceived value. An internal report may be less important than a report going to the customer (even if the report is an aggregate) and will likely help shift the emphasis from an internal, optional activity to a deliverable, required activity.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2009/12/implementing-agile-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tip: Netbeans 6.x scanning performance fix</title>
		<link>http://blog.mixu.net/2009/12/tip-netbeans-6-x-scanning-performance-fix/</link>
		<comments>http://blog.mixu.net/2009/12/tip-netbeans-6-x-scanning-performance-fix/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 13:33:40 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=574</guid>
		<description><![CDATA[I use Netbeans as my primary editor. It&#8217;s a great editor with pretty much all the features I would want built in (zero-configuration Mercurial support, code completion+navigation, unit testing support and more) .
The only caveat has been the performance &#8211; I was so frustrated I installed (and ultimately rejected) the vast majority of other (PHP) [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://www.netbeans.org/">Netbeans</a> as my primary editor. It&#8217;s a great editor with pretty much all the features I would want built in (zero-configuration Mercurial support, code completion+navigation, unit testing support and more) .</p>
<p>The only caveat has been the performance &#8211; I was so frustrated I installed (and ultimately rejected) the vast majority of other (PHP) editors. There is a simple fix if you have memory to spare: increase the heap size in the startup options. The Java VM default heap size seems to be way too small, causing a lot of swapping within the Java VM (while not using all the memory available from the OS perspective).</p>
<p><strong>Fixing Netbeans scanning performance </strong></p>
<p>Open /etc/netbeans.conf (e.g. C:\Program Files\Netbeans 6.x\etc\netbeans.conf). If you are on Windows 7, you need to start your text editor with Administrator privileges (right click and select Run as..).</p>
<p>Change the line: netbeans_default_options=&#8221;-J-client -J-Xverify:none &#8230;.&#8221;</p>
<p>by adding the following to the single line (AFTER &#8220;-J-client -J-Xverify:none&#8221;):</p>
<pre>-J-Xmx2048m -J-XX:+UseConcMarkSweepGC -J-XX:+CMSClassUnloadingEnabled
-J-XX:+CMSPermGenSweepingEnabled</pre>
<p>The -Xmx option changes the maximum heap size the Java virtual machine can address to 2048M from the default value (which is a &#8220;best guess&#8221; method). The other three are explained in the conf file.</p>
<p>DONE! Ever since I made this tweak (about two months ago) there have been no additional pauses at all. My theory is that the Netbeans scanning code was exhausting the heap, and a majority of the time &#8220;scanning&#8221; was instead spent dealing with the heap exhaustion. Now I will not say that it is reasonable for an IDE to consume 2 gigabytes of memory &#8211; but if that&#8217;s what it takes to fix performance, fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2009/12/tip-netbeans-6-x-scanning-performance-fix/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>I&#8217;m special &#8211; no you&#8217;re not!</title>
		<link>http://blog.mixu.net/2009/11/im-special-no-youre-not/</link>
		<comments>http://blog.mixu.net/2009/11/im-special-no-youre-not/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 01:24:47 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=469</guid>
		<description><![CDATA[People have an interesting tendency to believe that best practices do not apply to them. In this post I discuss the &#8220;I&#8217;m special so I should write my own web framework&#8221; case.
Take for instance:

Writing a CV. Best practice states that shorter is better, but oh so many people still want to have an eight-page CV [...]]]></description>
			<content:encoded><![CDATA[<p>People have an interesting tendency to believe that best practices do not apply to them. In this post I discuss the &#8220;I&#8217;m special so I should write my own web framework&#8221; case.</p>
<p>Take for instance:</p>
<ol>
<li><strong>Writing a CV.</strong> Best practice states that shorter is better, but oh so many people still want to have an eight-page CV because they are special.</li>
<li><strong>Web frameworks.</strong> Best practice states that using an established, documented and supported framework is better, but look at the proliferation of different MVC frameworks, ORM systems, CSS frameworks et cetera. And these are just the published examples: there are many many more in private use, because the authors were special and had special needs.</li>
<li><strong>Pitching.</strong> Best practice states that you should rehearse, keep your presentation short and focused, you should do market research and you should not rely on &#8220;chinese math&#8221;. Yet we have tons of pitches which are not rehearsed, overly long, unfocused, unresearched and based on lazy assumptions &#8211; because people expect to succeed because they are special.</li>
<li>You can probably think of ten more examples pretty quickly.</li>
</ol>
<p>Why oh why do we have to be in this situation? Can&#8217;t other people figure out that we don&#8217;t care about their overly long CV, their self-authored web framework and boring, unrealistics pitches?</p>
<p><strong>The &#8220;I&#8217;m special&#8221; excuse</strong></p>
<p>I hate the excuse that someone is special, and therefore does not need to follow good advice. <span style="background-color: #ffffff;">And yet I find myself compelled to, for instance, write my own web framework. <span style="background-color: #ffffff;"> </span></span></p>
<p><span style="background-color: #ffffff;"><span style="background-color: #ffffff;">As always the problem is other people. And the worst thing is that to other people, you are another person!</span></span></p>
<p>I will stick with the web frameworks example, because it is so common and easy to recognize as a problem.</p>
<p><strong>Writing your own web framework &#8211; are you really that special?</strong></p>
<p>Why on earth would anyone want to reinvent the wheel by writing yet another web framework? The justifications I think come down to one of:</p>
<ol>
<li><strong>Speed.</strong> The existing web frameworks are slow, because whomever wrote them was either incompetent or because they included the kitchen sink with their framework.</li>
<li><strong>Ease of coding.</strong> The existing web frameworks are horribly documented, and you prefer to reinventing the wheel to reading API documentation.</li>
<li><strong>Unique problems or novel ideas.</strong> You have a really unique problem or a really innovative new idea, and the existing frameworks do not support it.</li>
<li><strong>Learning experience.</strong></li>
</ol>
<p>And here are the reasons why you shouldn&#8217;t be doing it:</p>
<p><span style="background-color: #ffffff;"><strong>Speed</strong>.</span></p>
<p><span style="background-color: #ffffff;">Assume for a moment that all other developers are not incompetent (I know, it&#8217;s a huge jump for someone as special as you!). This implies that the reason frameworks are slower is that they have more features, which inevitably increases execution time. Thus you can quite safely assume that by the time you reach the same level of functionality as any top-tier web framework, you will be equally slow or slower. </span></p>
<p><span style="background-color: #ffffff;">The only way you will reach that point and know for sure is through grueling reinvention of the wheel.If you want certainty about performance, pick a reasonably fast existing framework and go make it slower by adding your own functionality. As Don Knuth said: <em>&#8220;We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.&#8221;</em></span></p>
<p><span style="background-color: #ffffff;">How many times have your customers called you and complained about performance? I&#8217;m not saying that performance does not matter &#8211; it clearly does &#8211; but this isn&#8217;t likely to be the most significant business, or even technical problem you encounter.</span></p>
<p><span style="background-color: #ffffff;"><strong>Ease of coding</strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">The lack of documentation is in my humble opinion a valid criticism of existing frameworks. While some documentation and tutorials exist for existing frameworks, the state of documentation in PHP web frameworks is rather bad.</span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">However, how well documented is your own framework? You will be familiar with it when coding it, but what about five years from now? What about the other people you will want to add if your project succeeds?</span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong>Unique problems or novel ideas</strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">How unique are your problems? Most of what web applications is a variation of a theme rather than a wholly novel problem. In fact, I have a hard time thinking of a counterexample. It is true that some frameworks make working with complex backend logic harder &#8211; but this is more a matter of picking the right framework; having the perfect framework won&#8217;t still make the backend logic any more simple.</span></strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">Is your novel idea actually useful? Imagine that you had built that crazy new framework with that neat idea &#8211; how much time would it save you in practice?</span></strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">I&#8217;m pretty convinced that this reason is in fact just an excuse for not liking the aesthetic feel of whatever frameworks were evaluated, rather than a real reason. The core reason is that whatever you are doing is complex, and having your own framework will only provide a slight relief at a huge maintenance cost.</span></strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong>Learning experience</strong></span></strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;"><strong><span style="font-weight: normal; background-color: #ffffff;">I think this is a legitimate reason. There is no substitute for learning by doing &#8211; but if you deploy that code into production, you are no longer learning: you have gone into the business of framework maintenance.</span></strong></span></strong></span></strong></span></p>
<p><span style="background-color: #ffffff;"><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2009/11/im-special-no-youre-not/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up SPF, SenderID and DKIM on Centos 5.3 using sendmail</title>
		<link>http://blog.mixu.net/2009/11/setting-up-spf-senderid-and-dkim-on-centos-5-3-using-sendmail/</link>
		<comments>http://blog.mixu.net/2009/11/setting-up-spf-senderid-and-dkim-on-centos-5-3-using-sendmail/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 10:52:51 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[How-to]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=510</guid>
		<description><![CDATA[The biggest four email providers Gmail, AOL, Hotmail and Yahoo (in this order according to Comscore) all implement some form of anti-spam techniques.
The main technologies are reverse DNS checking, SPF, SenderID, Domainkeys and DKIM. I will discuss all of these here and provide my tips on setting up SPF, SenderID and DKIM. Please keep in mind that [...]]]></description>
			<content:encoded><![CDATA[<p>The biggest four email providers Gmail, AOL, Hotmail and Yahoo (in this order <a href="http://www.informationweek.com/news/internet/google/showArticle.jhtml?articleID=219400298">according to Comscore</a>) all implement some form of anti-spam techniques.</p>
<p>The main technologies are reverse DNS checking, SPF, SenderID, Domainkeys and DKIM. I will discuss all of these here and provide my tips on setting up SPF, SenderID and DKIM. Please keep in mind that I am not an expert on email servers &#8211; but I hope this helps someone! It took me about half a day to figure this all out, so it is probably worth doing to improve your email delivery rates.</p>
<p><a href="http://zohrob.com/posts/entrepreneurs-guide-to-email-delivery-part-2.html">This blog entry from Dave Zohrom provides a nice discussion of sending email to a general audience</a> (part 2 of a 3-post series).</p>
<h2>Introduction</h2>
<p><strong>SPF or Sender Policy Framework</strong></p>
<p>SPF is easy to setup. It uses DNS TXT records to allow the email providers to check which servers are authorized to send email for a particular domain. The SPF project has done a great<strong> </strong>job at making this simple to setup. Just <a href="http://www.openspf.org/">go to their homepage</a> and use the setup wizard to generate the appropriate TXT records (the text field underneath &#8220;Deploying SPF&#8221;). Then change the values in your DNS records.</p>
<p>One thing to note is that if you have multiple servers and send email from a server with a different hostname (e.g. &#8220;mail.example.com&#8221;), you need to setup a record for that server as well. See <a href="http://www.openspf.org/FAQ/Common_mistakes">the common mistakes page on the SPF site</a>. Also, if you have hostnames that are not supposed to send mail, you ought to indicate this as well.</p>
<p>Another thing is that if you are using Google Apps for Your Domain to send email, then you will need to have to add &#8220;include:aspmx.googlemail.com&#8221; to also allow mail from Google to validate. See <a href="http://www.google.com/support/a/bin/answer.py?hl=en&amp;answer=33786">this answer for more</a>.</p>
<p><strong>SenderID from Microsoft</strong></p>
<p>SenderID is a variant of SPF, which for most practical cases is the same as SPF. Just setup SPF and this should produce a validation pass for SenderID as well. The semantics of the validation are a bit different,  but this does not seem to be a major practical problem. See testing tips below to make sure that this is also true in your case.</p>
<p><strong>DomainKeys</strong></p>
<p>DomainKeys is an older version of DKIM (DomainKeys Identified Mail) developed by Yahoo. Despite having very similar names, these ARE NOT the same!</p>
<p>Both DomainKeys and DKIM store public key information in DNS records and sign the message headers of every email sent. The recipient can then verify the signature.</p>
<p>DomainKeys was deprecated in 2007, but some email providers may still be using it. However, <a href="http://blog.deliverability.com/2009/09/franck-martin-on-the-future-of-dkim-and-domainbased-reputation-.html">these are a shrinking minority </a>and Yahoo does support the newer DKIM. <span style="background-color: #ffffff; ">Because of this I did not add DomainKeys support but opted only to use DKIM.</span></p>
<p><span style="background-color: #ffffff; ">You can add it to sendmail or Postfix using the dk-milter project code, but the unofficial RPM release <a href="http://www.topdog-software.com/oss/dk-milter/">is not maintained anymore</a>, which means you will need to install it from source (<a href="http://sourceforge.net/projects/dk-milter/">available via SourceForge</a>).</span></p>
<p><span style="background-color: #ffffff; "><strong>DKIM, or DomainKeys Identified Mail</strong></span></p>
<p><span style="background-color: #ffffff; ">DKIM on the other hand seems to be gaining momentum. It is used by Gmail, Yahoo and AOL and many others, and also works by publishing public keys via DNS TXT records and by signing the emails at the email server.</span></p>
<p><span style="background-color: #ffffff; ">To setup DKIM, you need an additional filter which takes the completed email and adds the DKIM signature to the email prior to sending it out.</span></p>
<p><span style="background-color: #ffffff;">Postfix and sendmail support &#8220;<a href="http://en.wikipedia.org/wiki/Milter">milters</a>&#8220;, which is apparently short for &#8220;mail filter&#8221;. There is a DKIM-milter package available for Centos at the EPEL repositories (see <a href="http://wiki.centos.org/AdditionalResources/Repositories">Centos page for 3rd party repos</a>).</span></p>
<h2><span style="background-color: #ffffff;">Setting up DKIM-milter with sendmail</span></h2>
<p><span style="background-color: #ffffff;">For Postfix, <a href="http://allaboutlamp.com/2009/09/setup-dkim-for-postfix-in-fedora-using-dkim-milter/">use these instructions from All About LAMP</a>. If you want to use sendmail as I did, here are my additional tips:</span></p>
<p><span style="background-color: #ffffff;"><strong>Steps 1-7 as in the linked tutorial.</strong></span></p>
<p><span style="background-color: #ffffff;"><strong>Step 8. Configure dkim-milter</strong></span></p>
<p><span style="background-color: #ffffff;">Open configuration file /etc/mail/dkim-milter/dkim-filter.conf and use the following configuration:</span></p>
<pre>Canonicalization simple
Domain example.com
KeyFile /some/path/to/whatever-your-keyfile-was
Selector name-of-the-selector
SignatureAlgorithm rsa-sha256
Socket inet:8891@localhost
Syslog Yes
Userid dkim-milter</pre>
<p>NOTE: you will be configuring dkim-milter to use the loopback interface instead of a socket file. I was unable to get dkim-milter to work via the socket file with sendmail. If you get it working, let me know.</p>
<p>You may also want to setup the following:</p>
<pre>SubDomains Yes
SyslogSuccess Yes
X-Header Yes</pre>
<p><span style="background-color: #ffffff;">The X-Header and Syslog options are useful for debugging. See the config file, each option should be documented there.</span></p>
<p><strong>Step 9. Change the default init.d script to use the loopback interface</strong></p>
<p><span style="background-color: #ffffff;">The default init script uses a socket, this needs to be changed. Open /etc/init.d/dkim-milter and change/comment the line:</span></p>
<pre>SOCKET=local:/var/run/${name}/${name}.sock</pre>
<p>to:</p>
<pre>SOCKET=inet:8891@localhost</pre>
<p><span style="background-color: #ffffff;"><strong>Step 10. Configure sendmail to use dkim-milter</strong></span></p>
<p>First a few reminders about sendmail configuration, remember that:</p>
<p>1. Sendmail comments DO NOT USE # as the comment, instead &#8220;dnl&#8221;  (<a href="http://www.sendmail.org/m4/intro_m4.html">delete through newline</a>) at beginning of the line is used to comment lines out.<br />
2. Sendmail configuration is built from the *.mc script files using the M4 macro processor.<br />
3. You need to install the sendmail-cf package for dependencies and install the m4 macro processor separately.<br />
4. In the configuration, the opening quote is a grave accent ` and the closing quote is a straight quote &#8216;.</p>
<p>To configure sendmail, open the &#8220;/etc/mail/submit.mc&#8221; file (which contains the settings for message sending; in older sendmail versions this config was in sendmail.mc).</p>
<p><strong>10.1 Edit submit.mc by adding the following entry to it:</strong></p>
<pre>INPUT_MAIL_FILTER(`dk-filter', `S=inet:8891@localhost')dnl</pre>
<p>(for example just before &#8220;FEATURE(`msp&#8217;, `[127.0.0.1]&#8216;)dnl&#8221;). Make sure that there are no <span style="background-color: #ffffff; font-family: Calibri; font-size: 15px; ">define(`confINPUT_MAIL_FILTERS&#8217;, `&#8230;&#8217;)dnl lines after this; if there are, you will need to add dkim-milter manually to the INPUT_MAIL_FILTERS list.</span></p>
<p><strong>10.2 Build and install a new submit.cf:</strong></p>
<pre>m4 /etc/mail/submit.mc &gt; submit.cf</pre>
<p>Tip: use m4 -d /etc/mail/submit.mc to debug first.</p>
<p><strong>10.3 Restart sendmail</strong></p>
<pre>service sendmail restart</pre>
<h2>Testing tips</h2>
<p><strong>Some possible errors:</strong></p>
<ol>
<li><span style="background-color: #ffffff; ">Errors getting the sendmail configuration generated: Check whether the dependencies (m4 and sendmail-cf) are installed and paths are correct.</span></li>
<li><span style="background-color: #ffffff; ">Errors starting sendmail: Make sure you replaced the correct files (submit.mc to submit.cf and sendmail.mc to sendmail.cf) and if you modified sendmail.mc in addition to submit.mc, make sure you have regenerated both.</span></li>
<li><span style="background-color: #ffffff; ">Errors starting dkim-milter: check the permissions on the key file</span></li>
<li><span style="background-color: #ffffff; ">Sendmail seems to ignore the dkim-milter, no X-dkim-milter header is in the mail even after you enabled the X-Header option in dkim-filter.conf: </span>
<ol>
<li><span style="background-color: #ffffff; ">Check /var/log/maillog.</span></li>
<li><span style="background-color: #ffffff; ">Sendmail seems to default to ignoring the milter if it cannot connect to it. This was the problem I ran into when using sockets; after switching to the loopback interface everything started working.</span></li>
<li><span style="background-color: #ffffff;">Also, check whether your mail is sent from a recipient for whom mail is supposed to be signed! If you haven&#8217;t setup your hostname, then this may lead to email not being signed (eg. hostname -F hostname plus /etc/hosts plus /etc/sysconfig/network).  See, for example <a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch21_:_Configuring_Linux_Mail_Servers#_Toc109364456">this tutorial for configuring sendmail</a>.</span></li>
<li><span style="background-color: #ffffff;">Also, check if you need to configure masquerading for Sendmail, see <a href="http://www.sendmail.org/m4/masquerading_relaying.html">http://www.sendmail.org/m4/masquerading_relaying.html</a></span></li>
</ol>
</li>
</ol>
<p><strong>Sending email from the console using only sendmail</strong></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;">Create a file with the following content:</p>
<pre>To: "Recipient name" &lt;john.doe@example.com&gt;
<span style="background-color: #ffffff; ">From: "Sender name" &lt;admin@example.com&gt;
Reply-To: admin@example.com
Subject: Hello world
This is the content of the message, end it with a line containing only a period as sendmail expects this.
.</span></pre>
<p>Then cat the file and pipe to sendmail -t:</p>
<pre>cat message.txt |sendmail -t</pre>
<p><strong>Checking all of the technologies mentioned above</strong></p>
<p>Port25.com offers a free service which check SPF, SenderID, DomainKeys and DKIM: <span style="background-color: #ffffff;"><a href="http://port25.com/domainkeys/">http://port25.com/domainkeys/</a></span></p>
<p><span style="background-color: #ffffff;">Quote: </span></p>
<ul>
<li><em>If you wish to receive the results at the address in the &#8220;mail_from,&#8221; the sample message should be sent to </em><a style="text-decoration: underline; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; color: #56759b;" href="mailto:check-auth@verifier.port25.com"><em>check-auth@verifier.port25.com</em></a><em>. </em></li>
<li><em>If you wish to receive the results at the address in the &#8220;from&#8221; header, the sample message should be sent to </em><a style="text-decoration: underline; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; color: #56759b;" href="mailto:check-auth2@verifier.port25.com"><em>check-auth2@verifier.port25.com</em></a><em>.</em></li>
</ul>
<p><em>A reply email will be sent back to you with an analysis of the message&#8217;s authentication status. The report will perform the following checks: SPF, SenderID, DomainKeys, DKIM and SpamAssassin.</em></p>
<p><strong>Additional resources:</strong></p>
<p><a href="http://allaboutlamp.com/2009/09/setup-dkim-for-postfix-in-fedora-using-dkim-milter/">How to Setup DKIM for Postfix in Fedora using dkim-milter</a></p>
<p><a href="http://allaboutlamp.com/2009/09/how-to-prevent-web-server-emails-from-being-marked-as-spam/">How to Prevent Web Server Emails from being Marked as SPAM</a></p>
<p><a href="http://domainkeys.sourceforge.net/"> DomainKey Implementor&#8217;s Tools and Library for email servers &amp; clients</a></p>
<p><a href="http://www.elandsys.com/resources/sendmail/dkim.html">Sendmail DKIM</a></p>
<p><a href="http://palma-seo.com/setting-dkim-spf-domainkeys-dns-bind">Setting up DKIM, SPF, Domainkeys DNS, Regular DNS on CentOS 5.3 at Pacificrack.com</a></p>
<p><a href="http://blog.nataprawira.com/tech/2009/08/15/how-to-manually-install-dkim-filter-with-sendmail/">How to manually install DKIM-Filter with Sendmail</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2009/11/setting-up-spf-senderid-and-dkim-on-centos-5-3-using-sendmail/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Picking the right nonfiction book</title>
		<link>http://blog.mixu.net/2009/11/picking-the-right-nonfiction-book/</link>
		<comments>http://blog.mixu.net/2009/11/picking-the-right-nonfiction-book/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 01:29:43 +0000</pubDate>
		<dc:creator>Mikito Takada</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[How-to]]></category>

		<guid isPermaLink="false">http://blog.mixu.net/?p=485</guid>
		<description><![CDATA[When it comes to reading, I&#8217;m spoiled! I notice I am getting more and more picky when it comes to ordering books from Amazon, which makes finding books that seem worth reading much harder to find.
Over the years I&#8217;ve read quite a pile of books particularly related to programming, general business, entrepreneurship and software engineering. [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to reading, I&#8217;m spoiled! I notice I am getting more and more picky when it comes to ordering books from Amazon, which makes finding books that seem worth reading much harder to find.</p>
<p>Over the years I&#8217;ve read quite a pile of books particularly related to programming, general business, entrepreneurship and software engineering. Now that I am reading up on new topics such as organizational development, lean methods and statistical research methods I am having real trouble finding books I would consider reading just based on the table of contents and Amazon reviews. This is probably a good thing, since the most efficient way to get information is to only read good books.</p>
<p>Here are a couple of guidelines for picking good non-fiction books:</p>
<ol>
<li><strong>Number of reviews.</strong> If there is only a small number of reviews, there is a risk that those reviews are written by the author or his/her friends. A book with more reviews is more credible, as is a book which has had more editions.</li>
<li><strong>Distribution of reviews. </strong>If the reviews are split between 5-star and 1-star reviews, the 5-star reviews are most likely fake. This is an absolutely disgusting practice, but unfortunately common.</li>
<li><strong>Credentials of the authors.</strong> If the authors are practitioners and not scientists, make sure they do not work for a consultancy. I have unfortunately 1-2 books that I did not check adequately and ended up getting a useless brochure book.</li>
<li><strong>The table of contents.</strong>
<ol>
<li><strong>What is the starting point of the discussion? </strong>This defines the prerequisite knowledge that you are expected to have. Reading a book which is for beginners is incredible boring, while reading an advanced book as a beginner is frustrating.Evaluate whether you have the prerequisite knowledge and could read the first few chapters without getting bored to tears. Remember that most popular business books are written for an audience that reads just a few books per year &#8211; this pretty much makes them too repetitive if you read more than that.</li>
<li><strong>What is the emphasis of the book? </strong>Is it oriented towards: a) practice or b) checklists, c) proper theory or d) undergraduate students textbook? (See below for more)</li>
<li><strong>How many pages are dedicated towards each topic? </strong>Don&#8217;t expect anything good from a book that has a 200 pages and cover 200 topics: that&#8217;s just one tiny page per topic.Good books don&#8217;t cover everything with the same small amount of pages, because everything is not equally important in real life.</li>
</ol>
</li>
<li><strong>The actual content of the reviews.</strong> Don&#8217;t bother with 5- or 4-star reviews, they will just tell you the book is good. Read the 1-star and 3-star reviews.See if the 1-star reviews seem to be justified or are just a result of the reviewer being an idiot (e.g. &#8220;Haven&#8217;t received book from Amazon&#8221; or &#8220;This book is too difficult&#8221; -reviews).3-star reviews are usually the best, since the author did like some aspects but did not like others. Pay attention to reviews that say that a book is too basic or simple. If this is said more than once, you probably don&#8217;t want to read that book &#8211; American writing in particular is already very verbose and too many books are written where a five-page article would do, hence reviews which state that the book is too simple should be taken very seriously.</li>
<li><strong>Number of and affiliation of authors. </strong>If all the authors are from the same institution or organization, the book is probably of lower quality. A huge warning sign is a &#8220;collection&#8221; book that has multiple chapters on different topics by the same authors, all from the same decade. This indicates that the authors have not bothered to contact the people who are at the top of their respective fields; articles which are all from the same decade are likely to be just a random set of articles which were written for the book rather than the result of good editorial work.</li>
<li><strong>Order of topics. </strong>Scientific collection books usually order the chapters so that the better and more widely applicable material is at the front of the book, and the more specialized and less interesting material is at the end. It is safe to assume that if the chapter that seems decent for your purpose is at the end of the book, you are better off finding a more specialized book.</li>
</ol>
<p><strong>Four classes of books:</strong></p>
<p>I would put books in four broad categories, two of which are useful and two are useless:</p>
<ol>
<li>Practical books</li>
<li>Academic books</li>
<li>Ego-booster books</li>
<li>Motivational books</li>
</ol>
<p><strong>Practical books: experience-based vs checklist books</strong></p>
<p>Practical books are in my opinion divisible into two categories: advice from practitioners and advice from people who like to write checklists. That is, you have books that are based on the experiences of a practitioner, and then you have books that are written by people who have not actually done that much but wanted to write a book and ended up writing a checklist &#8211; a list of things that might be of use without really emphasizing what is important.</p>
<p>Try to get a feel of the book from the preview (if you can&#8217;t, don&#8217;t buy it!), search for a couple of phrases that interest you. Does the author know what they are doing, or are they just collecting information from other people? Sometimes a &#8220;checklist book&#8221; is not bad &#8211; when you just need the basics and can&#8217;t be bothered to collect all the information. However, usually the experience-based book is better.</p>
<p><strong>Academic books: theory vs textbook</strong></p>
<p>When it comes to academic books, the two main types are proper theory books and textbooks. The more I have seen and read textbooks, the less I like them. Generally speaking they try to cover everything and end up saying nothing.</p>
<p>If you care about the topic, don&#8217;t get a textbook. Instead, get a proper collection of influential articles if it exists (ex. Oxford Handbook of X). You will perhaps not be fully prepared for everything you read, but you will learn something useful. Unlike after reading a textbook, where you just have fuzzy awareness of the fact that &#8220;all kinds of things happen&#8221; in a particular field.</p>
<p><strong>Ego-booster books: academic and practical</strong></p>
<p>There is also another category of books which are basically books written for the author&#8217;s ego. Some books are not written to be read, they are written either to impress others or to act as marketing tools.</p>
<p>The academic substitute for having a nice car sometimes seems to be writing an obtuse treatise which is downright hostile towards the reader, while consultancies in particular are guilty of writing books in which the answer to every question is &#8220;hire our consultancy&#8221;. The academic ego book is harder to spot, so pay attention when previewing the book.</p>
<p><strong>Motivational books: feeling good doesn&#8217;t make it so</strong></p>
<p>Finally, there is a category of fiction books which pretend to be non-fiction books. The motivational books may be a fun read at times, and are usually the most popular books in their category.</p>
<p>However, they are fiction for your entertainment. Feeling good is nice, but that does not change the fact that there are people who are knowledgeable, talented and well-connected doing whatever the book is about, and that feeling good does not make you knowledgeable, talented or well-connected.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mixu.net/2009/11/picking-the-right-nonfiction-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
