<?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>alexander kirk &#187; code</title>
	<atom:link href="http://alexander.kirk.at/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://alexander.kirk.at</link>
	<description></description>
	<lastBuildDate>Thu, 26 Jan 2012 12:30:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>preg_match, UTF-8 and whitespace</title>
		<link>http://alexander.kirk.at/2011/10/01/preg_match-utf-8-and-whitespace/</link>
		<comments>http://alexander.kirk.at/2011/10/01/preg_match-utf-8-and-whitespace/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 07:54:12 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=274</guid>
		<description><![CDATA[Just a quick note, be careful when using the whitespace character \s in preg_match when operating with UTF-8 strings. Suppose you have a string containing a dagger symbol. When you try to strip all whitespace from the string like this, you will end up with an invalid UTF-8 character: $ php -r 'echo preg_replace("#\s#", "", [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick note, be careful when using the whitespace character <code>\s</code> in <code>preg_match</code> when operating with UTF-8 strings.</p>
<p>Suppose you have a string containing a dagger symbol. When you try to strip all whitespace from the string like this, you will end up with an invalid UTF-8 character:</p>
<p><code>$ php -r 'echo preg_replace("#\s#", "", "†");' | xxd<br />
0000000: e280</code></p>
<p>(On a side note: <code>xxd</code> displays all bytes in hexadecimal representation. The resulting string here consists of two bytes <code>e2</code> and <code>80</code>)</p>
<p><code>\s</code> stripped away the <code>a0</code> byte. I was unaware that this character was included in the whitespace list, but actually it represents the <strong>non-breaking space</strong>.</p>
<p>So actually use the <a href="http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php">u (PCRE8) modifier</a> as it will be aware of the <code>a0</code> &#034;belonging&#034; to the dagger:</p>
<p><code>$ php -r 'echo preg_replace("#\s#u", "", "†");' | xxd<br />
0000000: e280 a0</code></p>
<p>By the way, <code>trim()</code> doesn&#039;t strip non-breaking spaces and can therefore safely be used for UTF-8 strings. (If you still want to trim non-breaking spaces with <code>trim</code>, <a href="http://php.net/manual/en/function.trim.php#98812">read this comment on PHP.net</a>)</p>
<p>Finally here you can see the ASCII characters matched by <code>\s</code> when using the u modifier.</p>
<p><code>$ php -r '$i = 0; while (++$i < 256) echo preg_replace("#[^\s]#", "", chr($i));' | xxd<br />
0000000: 090a 0c0d 2085 a0<br />
$ php -r '$i = 0; while (++$i < 256) echo preg_replace("#[^\s]#u", "", chr($i));' | xxd<br />
0000000: 090a 0c0d 20</code></p>
<p>Functions operating just on the ASCII characters (with a byte code below 128) are generally safe, as the multi-byte characters of UTF-8 have a leading bit of one (and are therefore above 128).</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2011/10/01/preg_match-utf-8-and-whitespace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restoring single objects in mongodb</title>
		<link>http://alexander.kirk.at/2011/05/31/restoring-single-objects-in-mongodb/</link>
		<comments>http://alexander.kirk.at/2011/05/31/restoring-single-objects-in-mongodb/#comments</comments>
		<pubDate>Tue, 31 May 2011 11:38:06 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[mongodb]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=261</guid>
		<description><![CDATA[Today I had the need to restore single objects from a mongodb installation. mongodb offers two tools for this mongodump and mongorestore, both of which seem to be designed to only dump and restore whole collections. So I&#039;ll demonstrate the workflow just to restore a bunch of objects. Maybe it&#039;s a clumsy way, but we&#039;ll [...]]]></description>
			<content:encoded><![CDATA[<p>Today I had the need to restore single objects from a <a href="http://www.mongodb.org/">mongodb</a> installation. mongodb offers two tools for this <tt>mongodump</tt> and <tt>mongorestore</tt>, both of which seem to be designed to <strong>only dump and restore whole collections</strong>.</p>
<p>So I&#039;ll demonstrate the workflow just to restore a bunch of objects. Maybe it&#039;s a clumsy way, but we&#039;ll improve this over time.</p>
<p>So, we have an existing backup, done with <tt>mongodump</tt> (for example through a daily, over-night backup). This consists of several <tt>.bson</tt> files, one for each collection.</p>
<ol>
<li>Restore a whole collection to a new database: <tt>mongorestore -d newdb collection.bson</tt></li>
<li>Open this database: <tt>mongo newdb</tt></li>
<li>Find the items you want to restore through a query, for example: <tt>db.collection.find({"_id": {"$gte": ObjectId("4da4231c747359d16c370000")}});</tt></li>
<li>Back on the command line again, just dump these lines to a new bson file: <tt>mongodump -d newdb -c collection -q '{"_id": {"$gte": ObjectId("4da4231c747359d16c370000")}}'</tt></li>
<li>Now you can finally import just those objects into your existing collection: <tt>mongorestore -d realdb collection.bson</tt></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2011/05/31/restoring-single-objects-in-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>trac Report for Feature Voting</title>
		<link>http://alexander.kirk.at/2011/01/27/trac-report-for-feature-voting/</link>
		<comments>http://alexander.kirk.at/2011/01/27/trac-report-for-feature-voting/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 17:07:50 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=222</guid>
		<description><![CDATA[I use trac for quite a few projects of mine. Recently I tried to find a plugin for deciding which features to implement next. Usually trac hacks has something in store for that, but not this time. I wanted to be able to create a ticket and then collect user feedback as comments for the [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://trac.edgewall.org/">trac</a> for quite a few projects of mine. Recently I tried to find a plugin for deciding which features to implement next. Usually <a href="http://www.trac-hacks.org/">trac hacks</a> has something in store for that, but not this time.</p>
<p>I wanted to be able to create a ticket and then collect user feedback as comments for the feature, with each piece of feedback being a vote for that feature, like this:</p>
<p><img src="http://alexander.kirk.at/wp-content/uploads/2011/01/report.png" alt="" title="report" width="331" height="135" class="size-full wp-image-227" /></p>
<p>After searching for a bit I came up with a solution by using just a report with a nicely constructed SQL query.</p>
<pre>SELECT p.value AS __color__,
   t.type AS `type`, id AS ticket, count(tc.ticket) as votes, summary, component, version, milestone,
   t.time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, ticket_change tc, enum p
  WHERE t.status <> 'closed'
AND tc.ticket = t.id and tc.field = 'comment' and tc.newvalue like '%#vote%'
AND p.name = t.priority AND p.type = 'priority'
GROUP BY id, summary, component, version, milestone, t.type, owner, t.time,
  changetime, description, reporter, p.value, status
HAVING count(tc.ticket) >= 1
 ORDER BY votes DESC, milestone, t.type, t.time</pre>
<p>So just by including &#034;#vote&#034; in a comment, it would count towards the number of votes. You can change this text to anything you want, of course. For example like this:</p>
<p><img src="http://alexander.kirk.at/wp-content/uploads/2011/01/vote-comments.png" alt="" title="vote-comments" width="343" height="527" class="alignnone size-full wp-image-235" /></p>
<p>I hope this can be useful for someone else, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2011/01/27/trac-report-for-feature-voting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS 2011 Alarm Clock Bug</title>
		<link>http://alexander.kirk.at/2011/01/11/ios-2011-alarm-clock-bug/</link>
		<comments>http://alexander.kirk.at/2011/01/11/ios-2011-alarm-clock-bug/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 09:07:04 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[observations]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=219</guid>
		<description><![CDATA[Just to add to the speculation about the causes of the 2011 alarm clock bug of iOS where the one-time alarms would not activate on January 1 and January 2, 2011. My guess is that the code that sets off the alarm takes day, month and year into account when checking whether the alarm should [...]]]></description>
			<content:encoded><![CDATA[<p>Just to add to the speculation about the causes of the <a href="http://www.macworld.com/article/156793/2011/01/ios_alarm.html">2011 alarm clock bug of iOS</a> where the one-time alarms would not activate on January 1 and January 2, 2011.</p>
<p>My guess is that the code that sets off the alarm takes day, month and year into account when checking whether the alarm should go off. But <b>instead of using the &#034;normal&#034; year</b>, an <a href="http://en.factolex.com/ISO_week_date">ISO-8601 year</a> could have been used. This type of year is <b>calculated by the number of the week</b> (with Monday as the first day of the week), thus for the week 52 (from December 27, 2010 to January 2, 2011) the respective year <b>remains 2010</b>.</p>
<p>When setting the date to January 1, 2012, the alarm doesn&#039;t go off as well (week 52 of 2011). This adds to my theory and also means that this hasn&#039;t been a one-time issue and requires a bug fix by Apple.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2011/01/11/ios-2011-alarm-clock-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging PHP on Mac OS X</title>
		<link>http://alexander.kirk.at/2008/12/26/debugging-php-on-mac-os-x/</link>
		<comments>http://alexander.kirk.at/2008/12/26/debugging-php-on-mac-os-x/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 18:18:15 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=104</guid>
		<description><![CDATA[I have been using Mac OS X as my primary operating system for a few years now, and only today I have found a very neat way to debug PHP code, like it is common for application code (i.e. stepping through code for debugging purposes). The solution is a combination of Xdebug and MacGDBp. I [...]]]></description>
			<content:encoded><![CDATA[<div class="factolex-glossary"><div class="factolex-glossary-header"><a href="http://en.factolex.com/">Glossary powered by Factolex.com</a></div><div class="factolex-glossary-content">No terms have been selected for this glossary.</div></div>
<p>I have been using Mac OS X as my primary operating system for a few years now, and only today I have found a very neat way to debug PHP code, like it is common for application code (i.e. stepping through code for debugging purposes).</p>
<p>The solution is a combination of <a href="http://www.xdebug.org/">Xdebug</a> and <a href="http://www.bluestatic.org/software/macgdbp/">MacGDBp</a>.</p>
<p><img src="http://alexander.kirk.at/wp-content/uploads/2008/12/macgdbp-debugger-300x227.png" alt="macgdbp-debugger" title="macgdbp-debugger" width="300" height="227" class="aligncenter size-medium wp-image-105" /></p>
<p>I am using the PHP package by <a href="http://www.entropy.ch/software/macosx/php/">Marc Liyanage</a> almost ever since I have been working on OS X, because it&#039;s far more flexible than the PHP shipped with OS X.</p>
<p>Unfortunately, installing Xdebug the usual <tt>pecl install xdebug</tt> doesn&#039;t work. But on the internetz you can find a <a href="http://www.designified.com/blog/article/60/compiling-installing-xdebug-for-php-525-entropych-build-on-os-x-105">solution to this problem</a>.</p>
<p>Basically you need to download the source tarball and use the magic command <tt>CFLAGS='-arch x86_64' ./configure --enable-xdebug</tt> for configuring it. (The same works for installing APC by the way)</p>
<p><code><br />
/usr/local/php5/php.d $ cat 50-extension-xdebug.ini<br />
[xdebug]<br />
zend_extension=/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so</p>
<p>xdebug.remote_autostart=on<br />
xdebug.remote_enable=on<br />
xdebug.remote_handler=dbgp<br />
xdebug.remote_mode=req<br />
xdebug.remote_host=localhost<br />
xdebug.remote_port=9000<br />
</code></p>
<p>Now you can use MacGDBp. There is an <a href="http://particletree.com/notebook/silence-the-echo-with-macgdbp/">article on Particletree</a> that describes the interface in a little more detail.</p>
<p>I really enjoy using this method to only fire up this external program, when I want to debug some PHP code, and can continue to use my small editor, so that I don&#039;t have to switch to a huge IDE to accomplish the same.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2008/12/26/debugging-php-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Website Optimization, a book by Andrew B. King</title>
		<link>http://alexander.kirk.at/2008/08/21/website-optimization-a-book-by-andrew-b-king/</link>
		<comments>http://alexander.kirk.at/2008/08/21/website-optimization-a-book-by-andrew-b-king/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 11:39:18 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[misc]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=90</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 5px"<a href=""><img src="http://alexander.kirk.at/img/9780596515089_cat.gif" alt="Website Optimization" border="0"/></a></div>
<p>This time I&#039;m reviewing a book by Andy King. Unlike <a href="http://alexander.kirk.at/2007/09/26/high-performance-web-sites/">High Performance website</a> by Steve Souders, it doesn&#039;t solely focus on the speed side of optimization, but it adds the art of Search Engine Optimization to form a compelling mix in a single book.</p>
<p>If you have a website that underperforms your expectations, this single book can be your one-stop shop to get all the knowledge you need.</p>
<p>Andy uses interesting examples of how he succeeded in improving his clients&#039; pages that illustrate well what he describes in theory before. He not only focuses on how to make your website show up at high ranks in search engines (what he calls &#034;natural SEO&#034;), but also discusses in detail how to use pay per click (PPC) ads to drive even more people to one&#039;s site. I especially liked how Andy describes how to find the best keywords to pick and also describes how to monitor success of PPC.</p>
<p>The part about the optimization for speed feels a little too separated in the book. It is a good read and provides similar content as Steve Souders book, though the level of detail feels a little awkward considering how different the audience for the SEO part of the book is. Still, programmers can easily get deep knowledge about how to get that page load fast. </p>
<p>Unfortunately Andy missed out a little on bringing this all into the grand picture. Why would I want to follow not only SEO but also optimize the speed of the page? There is a chapter meant to &#034;bridge&#034; the topics, but it turns out to be about how to properly do statistics and use the correct metrics. Important, but not enough to really connect the topics (and actually I would have expected this bridging beforehand).</p>
<p>Altogether I would have structured things a little different. For example: It&#039;s the content that makes search engines find the page and makes people return to a page, yet Andy explains how to pick the right keywords for the content first whereas he tells the reader how to create it only afterwards.<br />
Everything is there, I had just hoped for a different organization of things.</p>
<p>All in all, the book really deserves the broad title &#034;Website Optimization.&#034; Other books leave out SEO which usually is the thing that people mean when they want to optimize their websites (or have them optimized).</p>
<p>I really liked that the topics are combined a book and I highly recommend the book for everyone who wants to get his or her website in shape.</p>
<p>The book has been published by O&#039;Reilly in July 2008, ISBN <a href="http://www.oreilly.com/catalog/9780596515089/">9780596515089</a>. Also take a look at the <a href="http://www.websiteoptimization.com/secrets/">Website Optimization Secrets</a> companion site.</p>
<p>Thanks to Andy for providing me a review copy of this book.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2008/08/21/website-optimization-a-book-by-andrew-b-king/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upgrade WordPress Script</title>
		<link>http://alexander.kirk.at/2008/07/15/upgrade-wordpress-script/</link>
		<comments>http://alexander.kirk.at/2008/07/15/upgrade-wordpress-script/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 08:39:05 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=85</guid>
		<description><![CDATA[Whenever a new version of WordPress comes out (as just WordPress 2.6 did), it is somewhat of a pain to upgrade it. But not for me anymore, because I have created a small (and simple) script some versions ago which I would like to share with you. $ cat upgrade_wordpress.sh wget http://www.wordpress.org/latest.tar.gz mv www wordpress [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever a new version of WordPress comes out (as just <a href="http://wordpress.org/development/2008/07/wordpress-26-tyner/">WordPress 2.6</a> did), it is somewhat of a pain to upgrade it.</p>
<p>But not for me anymore, because I have created a small (and simple) script some versions ago which I would like to share with you.</p>
<p><code><br />
$ cat upgrade_wordpress.sh<br />
wget http://www.wordpress.org/latest.tar.gz<br />
mv www wordpress<br />
tar --overwrite -xzf latest.tar.gz<br />
rm latest.tar.gz<br />
mv wordpress www<br />
</code></p>
<p><tt>www</tt> is my document root and the script sits outside of it. It downloads the most recent version, extracts it while overwriting the already existing files. The script doesn&#039;t contain anything extra-ordinary, but makes upgrading real easy.</p>
<p>Of course this script is only useful if you have ssh access to your web server, but if you do that script might ease the (almost too frequent) pain of upgrading WordPress.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2008/07/15/upgrade-wordpress-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bash completion for the pear command</title>
		<link>http://alexander.kirk.at/2008/05/21/bash-completion-for-the-pear-command/</link>
		<comments>http://alexander.kirk.at/2008/05/21/bash-completion-for-the-pear-command/#comments</comments>
		<pubDate>Wed, 21 May 2008 11:59:33 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/?p=84</guid>
		<description><![CDATA[I am only scratching my own itch here, but maybe someone can use it or expand from it. I just always found annoying that pear run-tests tab gives all files instead of just *.phpt. This is what this snippet actually does. Paste this into the file /opt/local/etc/bash_completion on OSX (for me it is just before [...]]]></description>
			<content:encoded><![CDATA[<p>I am only scratching my own itch here, but maybe someone can use it or expand from it.</p>
<p>I just always found annoying that <tt>pear run-tests <i>tab</i></tt> gives all files instead of just <tt>*.phpt</tt>. This is what this snippet actually does.</p>
<p>Paste this into the file <tt>/opt/local/etc/bash_completion</tt> on OSX (for me it is just before <tt>_filedir_xspec()</tt>) or into a new file <tt>/etc/bash_completion.d/pear</tt> on Debian.</p>
<p><code><br />
# pear completion<br />
#<br />
have pear &#038;&#038;<br />
{<br />
_pear()<br />
{<br />
	local cur prev commands options command</p>
<p>	COMPREPLY=()<br />
	cur=${COMP_WORDS[COMP_CWORD]}</p>
<p>	commands='build bundle channel-add channel-alias channel-delete channel-discover channel-info channel-update clear-cache config-create config-get config-help config-set config-show convert cvsdiff cvstag download download-all info install list list-all list-channels list-files list-upgrades login logout makerpm package package-dependencies package-validate pickle remote-info remote-list run-scripts run-tests search shell-test sign uninstall update-channels upgrade upgrade-all'</p>
<p>	if [[ $COMP_CWORD -eq 1 ]] ; then<br />
		if [[ "$cur" == -* ]]; then<br />
			COMPREPLY=( $( compgen -W '-V' -- $cur ) )<br />
		else<br />
			COMPREPLY=( $( compgen -W "$commands" -- $cur ) )<br />
		fi<br />
	else</p>
<p>		command=${COMP_WORDS[1]}</p>
<p>		case $command in<br />
			run-tests)<br />
				_filedir 'phpt'<br />
				;;<br />
		esac<br />
	fi</p>
<p>	return 0<br />
}<br />
complete -F _pear $default pear<br />
}<br />
</code></p>
<p>Then re-source your <tt>bashrc</tt> or logout and re-login.</p>
<p>I am far from being an expert in bash_completion programming, so I hope someone can go on from here (or maybe has something more complete lying around?). </p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2008/05/21/bash-completion-for-the-pear-command/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>High Performance Web Sites, a book by Steve Souders</title>
		<link>http://alexander.kirk.at/2007/09/26/high-performance-web-sites/</link>
		<comments>http://alexander.kirk.at/2007/09/26/high-performance-web-sites/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 09:28:30 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/2007/09/26/high-performance-web-sites/</guid>
		<description><![CDATA[I&#039;d like to introduce you to this great book by Steve Souders. There already have been several reports on the Internet about it, for example on the Yahoo Developers Blog. There is also a video of Steve Souders talking about the book. The book is structured into 14 rules, which, when applied properly, can vastly [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 5px"><a href="http://www.oreilly.com/catalog/9780596529307/"><img src="http://alexander.kirk.at/img/hpws.gif" border="0" /></a></div>
<p>I&#039;d like to introduce you to this great book by <a href="http://stevesouders.com/">Steve Souders</a>. There already have been several reports on the Internet about it, for example on the <a href="http://developer.yahoo.net/blog/archives/2007/03/high_performanc.html">Yahoo Developers Blog</a>. There is also a <a href="http://video.yahoo.com/video/play?vid=1040890">video of Steve Souders talking about the book</a>.</p>
<p>The book is structured into <a href="http://developer.yahoo.com/performance/rules.html">14 rules</a>, which, when applied properly, can vastly improve the speed of a web site or web application.</p>
<p>Alongside with the book he also introduced <a href="http://developer.yahoo.net/yslow/">YSlow</a>, an extension for the Firefox extension <a href="http://www.getfirebug.com/">FireBug</a>. YSlow helps the developer to see how good his site complies with the rules Steve has set up.</p>
<p>I had the honour to do the technical review on this book, and I love it. Apart from some standard techniques (for example employing HTTP headers like Expires or Last-Modified/Etag), Steve certainly has some tricks up his sleave:</p>
<p>For instance he shows how it is possible to reduce the number of HTTP requests (by inlining the script sources) for first time visitors, while still filling up their cache for their next page load (see page 59ff).</p>
<p>The small down side of this book is that some rules need to be taken with care when applied to smaller environments; for example, it does not make sense (from a cost-benefit perspective) for everyone to employ a CDN. A book just can&#039;t be perfect for all readers.</p>
<p>If you are interested in web site performance and have a developer background, then buy this book (or <a href="http://safari.oreilly.com/9780596529307">read it online</a>). It is certainly something for you. </p>
<p>The book has been published by <a href="http://www.oreilly.com/catalog/9780596529307/">O&#039;Reilly</a> in September 2007, ISBN <a href="http://www.oreilly.com/catalog/9780596529307/">9780596529307</a>.</p>
<p>Some more links on the topic:
<ul>
<li><a href="http://www.oreillynet.com/fyi/blog/2007/09/yahoos_chief_performance_guru.html">Yahoo!&#039;s Chief Performance Guru Talks about Writing his New Book</a></li>
<li><a href="http://www.web2expo.com/presentations/webex2007/souders_steve.ppt">Slides from his presentation at WebEx 2007</a></li>
<li><a href="http://developer.yahoo.net/blog/archives/2007/08/yslow-podcast-screencast.html">Podcast on YSlow</a></li>
</ul>
<p><a href="http://technorati.com/tag/high+performance+web+apps" rel="tag">high performance web apps</a>, <a href="http://technorati.com/tag/steve+souders" rel="tag"> steve souders</a></p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2007/09/26/high-performance-web-sites/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Subversion: The Magic of Merging</title>
		<link>http://alexander.kirk.at/2006/10/12/subversion-the-magic-of-merging-2/</link>
		<comments>http://alexander.kirk.at/2006/10/12/subversion-the-magic-of-merging-2/#comments</comments>
		<pubDate>Thu, 12 Oct 2006 14:22:18 +0000</pubDate>
		<dc:creator>Alexander Kirk</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://alexander.kirk.at/2006/10/12/subversion-the-magic-of-merging-2/</guid>
		<description><![CDATA[Use svn merge -rhead:{date} to go back in time with a file]]></description>
			<content:encoded><![CDATA[<p>When programming professionally, <a href="http://subversion.tigris.org/">Subversion</a> is a must-have. Same for system administration: it&#039;s quite a good idea to keep your configuration files (e.g in Linux the whole <tt>/etc/</tt> directory) as a Subversion checkout.</p>
<p>So the goal of Subversion (or any other <a href="http://en.wikipedia.org/wiki/Source_control">Source Control system</a>) is to allow you to do something Apple will introduce with it&#039;s new Leopard operating system: <a href="http://www.apple.com/macosx/leopard/timemachine.html">Time Machine</a>. Go back in time (and restore a version of a file as it was on day x).</p>
<p>Using Subversion on a daily basis is quite easy. Just check in (<tt>svn ci</tt>) your changes after you have completed a certain task. When you work collaboratively, and someone else has committed some changes, you do a <tt>svn up</tt> and the changes of the others are applied to your codebase.</p>
<p>That&#039;s all you basically need. But how can you go back in time now?</p>
<p>So you poke around a bit and find that <tt>svn up</tt> has a parameter <tt>-r</tt> which let&#039;s you put your checkout to the state in which it was at a certain revision.</p>
<p>Let&#039;s suppose we know that something was ok on monday and is not today. So let&#039;s use the command from above to see what it looks like.<br />
<code><br />
~/project/trunk$ svn up -r {2006-10-09} app.php<br />
U app.php<br />
</code><br />
Voila, there it is. Now we choose to use that code now and throw away all changes that have been committed since. We modify the file a bit and do a check in:<br />
<code><br />
~/project/trunk$ svn ci -m "revert to monday" app.php<br />
Sending      app.php<br />
svn: Commit failed (details follow):<br />
svn: Your file or directory 'app.php' is probably out-of-date<br />
svn: The version resource does not correspond to the resource within the transaction.  Either the requested version resource is out of date (needs to be updated), or the requested version resource is newer than the transaction root (restart the commit).<br />
</code><br />
Uh.. ok. So you probably you know that error message already. It is also returned when you want to check something in on a file that has been changed by someone else since your last <tt>svn up</tt>.</p>
<p>When you check something into a subversion repository, one of the basic rules is that the file you want to commit is &#034;up to date&#034;, i.e. the revision number of your local file (updated by <tt>svn up</tt>) equals the number in the repository (on the server).</p>
<p>Ok, so, let&#039;s update our checkout so we can re-run the check in.<br />
<code><br />
~/project/trunk$ svn up<br />
G app.php<br />
</code><br />
So you discover the changes that happened since have been re-inserted to that file again. Maybe Subversion has alerted you of a conflict, because you changed some lines that have been modified since monday also.</p>
<p>Great! Basically we are back to where we started.</p>
<p>Let&#039;s not resign here, but rather use the appropriate command: <tt>svn merge</tt>. That command is mostly known for merging changes from one branch of development to another. But it can also help you to go back in time.</p>
<p>The parameters of <tt>svn merge</tt> are to specify a revision range, which changes to be merged, and a source &#8212; what part of the subversion repository should be searched for the changes.</p>
<p>Usually one would find this command used in a way like:<br />
<code><br />
~/project/trunk$ svn merge -r 15:26 ../branches/first_release/<br />
G app.php<br />
</code><br />
So with two revisions specified you define a range of changes which should be merged into the current checkout. Ok so how would us help this here? </p>
<p>You can also specify revisions <i>backwards</i>, to go back in time. So to undo the command form before you can write:<br />
<code><br />
~/project/trunk$ svn merge -r 26:15 ../branches/first_release/<br />
G app.php<br />
</code></p>
<p>To put it simple, Subversion generates a <tt>diff</tt> file behind the scenes that incorporates the changes between the given revisions. Then the changes are merged with the files in the same way the <tt>patch</tt> command (Linux, Unix, OS X, &#8230;) does it. When going back in time, the parameter <tt>-R</tt> is used which applies the patch in the reverse direction. Voila.</p>
<p>So as a final solution this leaves us with:<br />
<code><br />
~/project/trunk$ svn merge -r head:{2006-10-09} .<br />
U app.php<br />
~/project/trunk$ svn ci -m "revert to monday" app.php<br />
Sending      app.php<br />
Transmitting file data .<br />
Committed revision 27.<br />
</code></p>
<p>For further questions, the <a href="http://subversion.tigris.org/faq.html">Subversion FAQ</a> is a good starting point when you know exactly what you want (i.e. the correct terminology). (For example <i>reverting</i> does not mean to go back to a previous version of the file, but rather to remove the changes you did locally).</p>
<p>There is the <a href="http://svnbook.red-bean.com/">subversion book</a> (also published by <a href="http://www.oreilly.com/catalog/0596004486/">O&#039;Reilly</a>), of which the <a href="http://svnbook.red-bean.com/nightly/en/svn.tour.html">Guided Tour</a> is a good starting point.</p>
<p>The process I described above as a trial and error is also described in that book at <a href="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.undo">Undoing changes</a>.</p>
<p>Also <a href="http://bradchoate.com/weblog/2006/07/27/oscon-subversion-best-practices">OSCON: Subversion Best Practices</a>, a transcript of a talk given by the subversion creators (Ben Collins-Sussman and Brian W. Fitzpatrick) by Brad Choate has some good tips.</p>
<p>Have fun :)</p>
<p><a href="http://technorati.com/tag/subversion" rel="tag">subversion</a>, <a href="http://technorati.com/tag/merge" rel="tag"> merge</a>, <a href="http://technorati.com/tag/revert" rel="tag"> revert</a>, <a href="http://technorati.com/tag/time+machine" rel="tag"> time machine</a></p>
]]></content:encoded>
			<wfw:commentRss>http://alexander.kirk.at/2006/10/12/subversion-the-magic-of-merging-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.456 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-04 12:36:09 -->

