<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="/templates/funkky/atom.css" type="text/css" ?>

<feed 
   xmlns="http://www.w3.org/2005/Atom"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <link href="http://usrportage.de/feeds/atom.xml" rel="self" title="/usr/portage" type="application/x.atom+xml" />
    <link href="http://usrportage.de/"                        rel="alternate"    title="/usr/portage" type="text/html" />
    <link href="http://usrportage.de/rss.php?version=2.0"     rel="alternate"    title="/usr/portage" type="application/rss+xml" />
    <title type="html">/usr/portage</title>
    <subtitle type="html">As A Result of the Objective Gray</subtitle>
    
    <id>http://usrportage.de/</id>
    <updated>2009-01-03T15:56:05Z</updated>
    <generator uri="http://www.s9y.org/" version="1.4-beta2">Serendipity 1.4-beta2 - http://www.s9y.org/</generator>
    <dc:language>en</dc:language>

    <entry>
        <link href="http://usrportage.de/archives/907-Seven-Things.html" rel="alternate" title="Seven Things" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2009-01-03T12:06:08Z</published>
        <updated>2009-01-03T15:56:05Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=907</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=907</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/907-guid.html</id>
        <title type="html">Seven Things</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>I&#8217;ve got tagged by <a href="http://www.deshong.net/?p=145">Brian DeShong</a> and <a href="http://www.manuel-pichler.de/">Manuel Pichler</a> to write down seven facts about me. Quick and easy:
	<ul>
		<li>Sung in a boys choir and had professional vocal training for almost ten years. We wore funny suits and it was quite cool</li>
		<li>Sung the alto solo of the Paul McCartney opera <a href="http://en.wikipedia.org/wiki/Liverpool_Oratorio">Liverpool Oratorio</a>. You didn&#8217;t even know Paul McCartney wrote operas, right?</li>
		<li>Went to a Rudolf Steiner school for 13 years. This was not so cool as I&#8217;m not enough into mystery</li>
		<li>I&#8217;m together with a upcoming geologist. I&#8217;m trying to get her into the oil business against her will. We actually met on a dating portal but I have an excuse: I worked there at that time.</li>
		<li>I read most of the works of Theodor W. Adorno, the important ones from Karl Marx and it made me a better programmer. Not.</li>
		<li>I still think smoking is one of the coolist habits ever.</li>
	</ul></p>

	<p>So here are my nominated victims:
	<ul>
		<li><a href="http://sitzpisser.net/">Johannes Steidl</a>, my best friend, because I want to know if I guess right on what the facts are</li>
		<li><a href="http://pooteeweet.org/">Lukas Smith</a> for his efforts in bringing more structure in the <span class="caps">PHP</span> core development process</li>
		<li><a href="http://schlueters.de/blog/">Johannes Schlüter</a> &#8216;cause I know he will hate it</li>
		<li><a href="http://www.kasn.de/">Karsten Gohm</a> a new collegue of mine</li>
		<li><a href="http://mzacher.de/">Marc Zacher</a>, the guy who had an <a href="http://flickr.com/photos/mastayoda/sets/72157601115364510/">intimate affair with Bart</a></li>
		<li><a href="http://octavian.supersized.org/">Marc Jakubowski</a> because of stuff like <a href="http://twitter.com/octavian/status/1082515572">that</a></li>
	</ul></p> 
            </div>
        </content>
        <dc:subject>Me</dc:subject>
<dc:subject>Meme</dc:subject>
<dc:subject>PHP</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/906-Ubuntu-Linux-on-an-Asus-EeePC-901.html" rel="alternate" title="Ubuntu Linux on an Asus EeePC 901" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-12-28T17:43:36Z</published>
        <updated>2008-12-29T08:37:05Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=906</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=906</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/906-guid.html</id>
        <title type="html">Ubuntu Linux on an Asus EeePC 901</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>I got an Asus EeePC for Christmas. As a long time Linux user the pre-installed Windows XP version had a very short life, something around ten minutes to check that the hardware is working. In general installing Linux is not very hard, actually the harder part was to build the install <span class="caps">USB</span> stick, as the EeePC has no disk drive. But first a few sentences about the EeePC.</p>

	<h4>The Good</h4>

	<p>The device is small and looks cute so the girl acceptance level is pretty high as my personal girl acceptance level test girl confirmed. It just feels right. The weight is alright, 1.1kg is fair enough. Three <span class="caps">USB</span> slots, one more than my Apple Mac Book, so good too. <span class="caps">VGA</span> out, fine, SD card slot, alright, not that I need it but &#8230; RaLink WiFi chip, Gigabit network, built-in web cam, Bluetooth, synaptics touch pad. That&#8217;s pretty good, sounds like a complete computer, doesn&#8217;t it? The display resolution is 1024&#215;600 &#8211; good for such a small device.</p>

	<h4>The Bad</h4>

	<p>As as result of the overall size, the keyboard is of course small too. Also I&#8217;m now writing this entry on it, it takes some time to get used to it. The position of the pipe/less/greater-key is annoying as it can only be reached in combination with the fn modifier key. This is not very convenient for a programmer. The rest of the layout is more or less standard and it doesn&#8217;t take so long to not miss every key.</p>

	<h4>The Ugly</h4>

	<p>When I tried Bluetooth the first time, the device was not detected at all. Neither on Windows nor on Linux. But while changing other stuff I found out that the Bluetooth adapter was disabled in the <span class="caps">BIOS</span>. It is a nice feature to allow to hard disable some features in the <span class="caps">BIOS</span> but disabling anything by default seems not like the most clever idea. So please fix, Asus.<br />
Sadly the EeePC suffers a heat problem. If you stress it a bit it gets really hot on the downside (like the Mac Books). So don&#8217;t put it on your naked thigh.</p>

	<h4>Choosing the Right Distribution</h4>

	<p>I have the model with two solid state discs which makes a total of 12GB disk space. Not very much but enough for my use cases (and I always wanted to have a <span class="caps">SSD</span> based device). I decided to go with Ubuntu:http://ubuntu.com also I normally prefer <a href="http://gentoo.org">Gentoo</a> because of the size. Source base distributions like Gentoo don&#8217;t differentiate between the actual packages and the header files so a complete Gentoo installations takes a lot more disk space than any binary distribution. Additionally, it was Christmas evening and I wanted something quick. While Gentoo is flexible, it is not quick to install.<br />
Although I chose Ubuntu, I would roughly guess that Fedora or SuSE would work fine too, please leave a comment if you have an experience to share.<br />
I chose Ubuntu mainline, not <a href="http://www.eeebuntu.org/">Eeebuntu</a> because I want to have the latest and greatest Ubuntu and I can configure my panel myself.</p>

	<h4>Preparing the Installation</h4>

	<p>Before you read on further make sure you understand that this is not about a dual boot installation. I completely removed the Windows system, so please make sure this is what you want too.<br />
First of all we need a boot medium. There is an SD card slot and a number of <span class="caps">USB</span> ports, so the alternatives are <span class="caps">USB</span> disk drive, SD card, <span class="caps">USB</span> stick. I chose the latter but the rest should work too. Creating an <span class="caps">USB</span> boot stick requires a bit of manual work: download the Ubuntu Intrepid Ibex (8.10) <span class="caps">ISO</span> image for 32bit computers (Atom <span class="caps">CPU</span>) then:
	<ul>
		<li>Format the stick with FAT32: <code>mkfs.vfat /dev/sdX1</code></li>
		<li>Add an <span class="caps">MBR</span> to the stick: <code>cat /usr/share/syslinux/mbr.bin &#62; /dev/sdX</code></li>
		<li>Install syslinux: <code>syslinux -s /dev/sdX1</code></li>
		<li>Mount the <span class="caps">ISO</span> image: <code>mount -o loop &#60;iso&#62; /mnt/iso</code></li>
		<li>Mount the <span class="caps">USB</span> stick: <code>mount /dev/sdX1 /mnt/stick</code></li>
		<li>Copy the contents of the image to the stick: <code>cp /mnt/iso/.* /mnt/stick</code></li>
		<li>Fix the dists directory: <code>mv /mnt/stick/dists/intrepid /mnt/stick/dists/stable</code></li>
		<li>Rename isolinux directory to syslinux: <code>mv /mnt/stick/syslinux /mnt/stick/isolinux</code></li>
		<li>Rename isolinux.cfg to syslinux.cfg: <code>mv /mnt/stick/isolinux/syslinux.cfg /mnt/stick/isolinux/isolinux.cfg</code></li>
	</ul></p>

	<h4>Installing Ubuntu from the Stick</h4>

	<p>Now the <span class="caps">USB</span> boot stick is ready. Just plug it in, type F1 to select the boot menu, choose the stick as the boot medium, boot from it and install Ubuntu as usual. Everything is detected and configured correctly including the synaptics touch pad, web cam and screen. The only missing components are the WiFi adapter and the specials keys. The keys generate <span class="caps">ACPI</span> events so it should not be hard to get them running. However, I don&#8217;t use specials keys so I don&#8217;t care.<br />
The WiFi adapter is a RaLink RT2860 and RaLink provides a driver for it. You could download and manually compile this driver but I found it more convenient to have specific package for it.</p>

	<h4>Installing the Right Kernel</h4>

	<p>The linux-eeepc-lean kernel from <a href="http://array.org/ubuntu/">array.org</a> works really well and includes support for the RaLink WiFI adapter. Just follow the <a href="http://array.org/ubuntu/setup-intrepid.html">setup instructions</a> to install it. Then boot the new kernel and, if everything works fine, edit <strong>/boot/grub/menu.lst</strong> to use the eeepc lean kernel as the default kernel. The Ubuntu installation is now done, enjoy!</p> 
            </div>
        </content>
        <dc:subject>EeePC</dc:subject>
<dc:subject>Gadgets</dc:subject>
<dc:subject>Hardware</dc:subject>
<dc:subject>Linux</dc:subject>
<dc:subject>Ubuntu</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/905-SSH-configuration-parameters.html" rel="alternate" title="SSH configuration parameters" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-10-14T15:46:15Z</published>
        <updated>2008-10-21T14:04:33Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=905</wfw:comment>
    
        <slash:comments>3</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=905</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/905-guid.html</id>
        <title type="html">SSH configuration parameters</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>Having a number of hosts following the same naming scheme is good, defining them is repetitive and boring. Maybe we could patch <span class="caps">SSH</span> to achieve something like this. Take a look at an example for ssh-config:</p>

<pre><code>Host myhost%02d
    User lars
    Hostname myhost$1.example.com
</code></pre>

	<p><code>ssh myhost02</code> would be expanded and as a result would resolve to myhost02.example.com.</p> 
            </div>
        </content>
        <dc:subject>Administration</dc:subject>
<dc:subject>Bowl Of Cherries</dc:subject>
<dc:subject>SSH</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/904-Antipattern-chaining-stateless-protocol-requests.html" rel="alternate" title="Antipattern: chaining stateless protocol requests" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-09-24T18:55:13Z</published>
        <updated>2008-10-03T15:20:59Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=904</wfw:comment>
    
        <slash:comments>3</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=904</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/904-guid.html</id>
        <title type="html">Antipattern: chaining stateless protocol requests</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>As we all know, <span class="caps">HTTP</span> is a stateless protocol. We do all sort of hacks to add state, like <code>ext/session</code> in <span class="caps">PHP</span>. While such hacks work great for a lot of use cases, we should remind ourselves that they are hacks. There is a phenomenon of <strong>state creep</strong>: coupling unrelated <span class="caps">HTTP</span> requests. Think of a page that references a thumbnail in an <code>&#60;img/&#62;</code>-tag and the picture is generated as needed: it would be possible to generate that image in the context of the request that embeds that image. So the template calls a helper to generate the thumbnail and the thumbnail is generated in the file system.</p>

	<p>While this works well for a single host, your personal weblog about cooking and cats, it won&#8217;t work for something serious. When you start load balancing between two webserver nodes you are set on fire as you can&#8217;t guarantee that the image is present on the correct node (beside you are generating the image n times where n is the number of nodes). The solution is not that hard: pregenerate all the images with a queuing system and display <strong>&#8220;This image is currently not available&#8221;</strong>-placeholders as long as they are not ready or &#8211; in case of little image uploads &#8211; generate them when uploading the image. The other option is to generate them on the fly when they are requested. If you do the latter, do it in the context of the request that tries to receive the image, not in the embedding context (the page that embeds the image). Generating on the fly means that you deliver your files through <span class="caps">PHP</span> or something similar: this is fine as long as you have an <span class="caps">HTTP</span> accelerator in place.</p>

	<p>One of the systems that does it in the way described above is <a href="http://drupal.org">Drupal</a>. I&#8217;ve implement MogileFS for image storage and retrieval for Drupal and let me say, it was not a pleasure.</p>

	<p>On a side note: <span class="caps">HTTP</span> 1.1 allows resources to be fetched in parallel, which makes generating images in the wrong context even worse from a user experience point of view, as the page will not show up until each thumbnail is generated.</p> 
            </div>
        </content>
        <dc:subject>Cluster</dc:subject>
<dc:subject>Patterns</dc:subject>
<dc:subject>PHP</dc:subject>
<dc:subject>Scalability</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/903-8-Hints-out-of-Testing-Turmoil.html" rel="alternate" title="8 Hints out of Testing-Turmoil" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-09-19T15:55:00Z</published>
        <updated>2008-10-08T22:37:18Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=903</wfw:comment>
    
        <slash:comments>6</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=903</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/903-guid.html</id>
        <title type="html">8 Hints out of Testing-Turmoil</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<ol>
		<li>Have a continuous integration solution in place. Really. If you don&#8217;t, you just burn money by writing tests. I would go so far and say, if you don&#8217;t have continuous integration, you should stop writing unit tests and do click testing. Let your CI system generate <span class="caps">API</span> docs, high level docs, code coverage report, testdox and every statical analysis info you generate.</li>
		<li>The definition of &#8220;tests pass&#8221; is &#8220;tests pass on the continous integration system&#8221;. &#8220;Works for me&#8221; has neither a place in the bugtracker nor everywhere else.</li>
		<li>If you can&#8217;t test it, the architecture is most likely wrong (exceptions are sessions and caching related code which is generally hard to test). Testability should be your main concern when writing code. What&#8217;s the use of fast or wonderful looking code, if you can&#8217;t repeatable prove it is working?</li>
		<li>Prefer method calls over annotations. A typo in <code>setExpectedException</code> will trigger a transparent error, while a typo in <code>expectedException</code> will lead to <a href="http://xunitpatterns.com/Obscure%20Test.html">Obscure Test</a>, and most likely a Mistery Guest.</li>
		<li>Run the whole test harness twice. This will hellp to identify setup/teardown bugs. Create a random test suite to identify the hard to track mistakes.</li>
		<li>Run your testsuite really often. We run it with 15 seconds delay every minute and I&#8217;m pretty happy with it.</li>
		<li>Use good test names that describe the behavior of the unit. The behavior is not the unit you test itself, that&#8217;s what I see in the code, it is something like &#8220;calling register changes the status of the user to foobar&#8221; so the good test name would be &#8220;testRegisterChangesTheStatus &#8230;&#8221;.</li>
		<li>Aim for 100% code coverage. 95% is nothing to be proud about, I can guarantee, the missing 5% will be the hardest part.</li>
	</ol> 
            </div>
        </content>
        <dc:subject>PHP</dc:subject>
<dc:subject>PHPUnit</dc:subject>
<dc:subject>Unit testing</dc:subject>
<dc:subject>xUnit</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/902-Recovering-a-software-RAID.html" rel="alternate" title="Recovering a software RAID" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-09-13T01:17:22Z</published>
        <updated>2008-09-20T15:16:26Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=902</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=902</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/902-guid.html</id>
        <title type="html">Recovering a software RAID</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>The scenario: my <span class="caps">RAID</span> crashed because I&#8217;ve messed around with the partition table of one of the disks in there. This results in a <span class="caps">RAID</span> array not being able to assemble itself because the superblock of the messed up device is invalid. The trick is pretty easy: just recreate the whole <span class="caps">RAID</span> with <code>mdadm</code>. The existing metadata will not be overwritten, the current information is just replicated. I  used to have a simple RAID1, but I&#8217;ve now recreated it as an incomplete RAID5 (<code>--level=5</code>, <code>--raid-devices=2</code>) as the missing disk is soon to be bought.</p>

<pre><code>$ mdadm --create /dev/md0 --level=5 --raid-devices=2 /dev/&#60;original&#62; /dev/&#60;crashed&#62;
</code></pre>

	<p>If you like to stick with a RAID1, and not doing the migration to RAID5 along the way, just use <code>--level=1</code> instead. I&#8217;m not really sure if the order of the disks matter and I&#8217;m not brave enough to find it out.</p>

	<p>Tomorrow I&#8217;m going to buy the next disk for the <span class="caps">RAID</span> to make sure the redundancy level is alright. Generally I&#8217;m pretty amazed that this kind of setup is so robust. Even me messing around with it can&#8217;t bring it down.</p> 
            </div>
        </content>
        <dc:subject>Gentoo</dc:subject>
<dc:subject>Linux</dc:subject>
<dc:subject>mdadm</dc:subject>
<dc:subject>RAID</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/899-Testing-PHP-5.3-alpha1.html" rel="alternate" title="Testing PHP 5.3 alpha1" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-08-03T17:22:50Z</published>
        <updated>2008-08-07T21:23:04Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=899</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=899</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/899-guid.html</id>
        <title type="html">Testing PHP 5.3 alpha1</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>Finally <a href="http://schlueters.de/">Johannes Schlüter</a> baked a first alpha-tarball for <span class="caps">PHP</span> 5.3. The new version contains a <a href="http://cvs.php.net/viewvc.cgi/php-src/NEWS?view=markup&amp;pathrev=PHP_5_3">huge amount of new features</a>, like closures, namespaces and late static binding. Such a huge amount requires thorough testing: if you are using a <span class="caps">PHP</span> application you would like to see fully working with our brand new version or you are developing a <span class="caps">PHP</span> application, this is your chance to make sure everything will go smoothly. If you are a web hosting provider, do your performance benchmarks now!<br />
If you are, accidentally, using the <a href="http://gentoo.org">Gentoo Linux distribution</a>, I have something for you: in my personal <a href="http://svn.usrportage.de/php-overlay/"><span class="caps">PHP</span> overlay</a> you can find an ebuild for <span class="caps">PHP</span> 5.3.0_alpha1. A few warnings: currently, <strong>ext/fileinfo</strong> does not compile because of <a href="http://bugs.php.net/bug.php?id=45636">#45636</a> and of course I did not test all  possible USE-flag combinations. If you experience problems with it, just leave a comment here.</p> 
            </div>
        </content>
        <dc:subject>Gentoo</dc:subject>
<dc:subject>PHP</dc:subject>
<dc:subject>Testing</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/898-Specific-env-vars-for-Gentoo-packages.html" rel="alternate" title="Specific env vars for Gentoo packages" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-08-02T13:42:35Z</published>
        <updated>2008-08-02T15:15:09Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=898</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=898</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/898-guid.html</id>
        <title type="html">Specific env vars for Gentoo packages</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>Since Gentoo Portage introduced the package specific configuration in <strong>/etc/portage</strong> there was one thing I always missed: specifying environment variables per package. Some environment variables you might want to specify per package are <strong>CFLAGS</strong>, <strong>CXXFLAGS</strong> and <strong>FEATURES</strong>. Especially when you do debugging, some packages should not be stripped, which is the perfect use case for the <strong>FEATURES</strong> environment variable. While specifying USE-flags and keywords per package, the rest is not that easy. <a href="http://hoffie.info/" title="hoffie">Christian Hoffmann</a> dropped me a link to <a href="http://www.mail-archive.com/gentoo-portage-dev@lists.gentoo.org/msg00585.html">this mail</a>: the tip there works fine. I&#8217;ve played around with it and implemented it slightly differently: first, I would like to be informed which environment files are read and second I changed the resolution order so that the specific configuration inherits from the more generic. So this is what my <strong>/etc/portage/bashrc</strong> looks like now:<br />

[geshi lang=bash]
for conf in ${PN} ${PN}-${PV} ${PN}-${PV}-${PR}; do
	env=/etc/portage/env/${CATEGORY}/${conf}.env
	if [[ -f  ${env} ]]; then
		einfo "Reading specific environment from ${env}"
		. ${env}
	fi
done
[/geshi]
<br />
For dev-lang/php-5.2.6-r3 I can use three different files to customize the build environment: <strong>/etc/portage/env/dev-lang/php.env</strong> would apply for all <span class="caps">PHP</span> ebuilds, <strong>/etc/portage/env/dev-lang/php-5.2.6.env</strong> for all revision of the ebuild for 5.2.6 and <strong>/etc/portage/env/dev-lang/php-5.2.6-r2.env</strong> for the exact ebuild. My <strong>/etc/portage/env/dev-lang/php.env</strong> file now looks like this to disable stripping the binaries after emerging them and keeping the working directory for better backtraces:<br />

[geshi lang=bash]
FEATURES="${FEATURES} nostrip keepwork"
[/geshi]
</p> 
            </div>
        </content>
        <dc:subject>Debugging</dc:subject>
<dc:subject>Gentoo</dc:subject>
<dc:subject>PHP</dc:subject>
<dc:subject>Portage</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/897-Antipattern-the-verbose-constructor.html" rel="alternate" title="Antipattern: the verbose constructor" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-07-30T23:44:24Z</published>
        <updated>2008-09-25T12:55:08Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=897</wfw:comment>
    
        <slash:comments>48</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=897</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/897-guid.html</id>
        <title type="html">Antipattern: the verbose constructor</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>Constructors are often used to shortcut dependency injection and parameter passing on instantiation. This is a valid practice and often leads to shorter code. Consider the following example (a simple value object, often used to not mess around with floats and to keep currency and amount together):</p>

<pre><code>class Money
{
    protected $_amount;
    protected $_currency;
    protected $_divisor;
    public function __construct(
        $amount = null, $currency = null, $divisor = null)
    {
        if ($amount !== null)
            $this-&#62;setAmount($amount);
        if ($current !== null)
            $this-&#62;setCurrency($currency);
        if ($divisor !== null)
            $this-&#62;setDivisor($divisor);
    }
    ... setter and getter ...
}
</code></pre>

	<p>Now consider instantiating this object. Instead of creating a new instance of &#8220;Money&#8221; and calling three setter, everything can be done compactly in the constructor.</p>

	<p>bc . $money = new Money(13200, &#8216;EUR&#8217;, 100);</p>

	<p>So for the money object this works pretty well. The code is easy to read, but wait, the first argument can be grasped easily, the second too, but the third? It is not too obvious that it is a divisor is passed. An alternative would be changing the constructor to accept an array. This is a replacement for true named arguments, as e.g. <a href="http://www.diveintopython.org/power_of_introspection/optional_arguments.html">Python</a> supports. <a href="http://solarphp.com/">Solar</a> uses that a lot, as well as the <a href="http://framework.zend.com">Zend
Framework</a>.</p>

<pre><code>$money = new Money(
    array(
        &#39;amount&#39; =&#62; 13200,
        &#39;currency&#39; =&#62; &#39;EUR&#39;,
        &#39;divisor&#39; =&#62; 100
    )
);
</code></pre>

	<p>Much better readable but does your <span class="caps">IDE</span> code completion works? And what happens if you pass &#8220;amoµnt&#8221;, because your fingers are as clumsy as mine? Exactly, the parameter will be silently ignored.<br />
But look at this:</p>

<pre><code>$money = new Money();
$money-&#62;setAmount(13200);
$money-&#62;setCurrency(&#39;EUR&#39;);
$money-&#62;setDivisor(100);
</code></pre>

	<p>It is at least equally short, readable, your <span class="caps">IDE</span> works and if you have problems with the dimensions of your keys on your keyboard (they are too small, it has nothing to do with your fingers) you will be warned. But we could even have an even shorter example while maintaining the readability. With fluent interfaces we would get the following:</p>

<pre><code>$money = new Money();
$money-&#62;setAmount(13200)-&#62;setCurrency(&#39;EUR&#39;)-&#62;setDivisor(100);
</code></pre>

	<p>Wonderful! If you want, you can add a newline between each object operator and you would have the same amount of lines but less dense code (sad that we don&#8217;t have fluent constructors, isn&#8217;t it?). Sometimes setters are so elegant.</p>

	<p>So until know one thing should be clear: it is not just about easily writing the code, but about the next guy understanding it too. Because you never write code for yourself. Never. But let&#8217;s investigate some real live example. I work with a framework that allows me to define really nifty business logic by just sticking together a bunch of fields and every field having a bunch of  validators and filters attached.</p>

<pre><code>class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition-&#62;addField(new StringField(&#39;username&#39;, true, null, true));
    }
    protected function _getStorageClass()
    {
        return &#39;UserStorage&#39;;
    }
}
</code></pre>

	<p>All the time I write such a definition, I need to look into the code to check the order of the parameters. I can remember the first parameter, but the rest is too similar. To explain it: the second parameter specifies whether the field is required, the third expects a default parameter and the fourth indicates whether the value can be changed after it has been set once. I&#8217;ve talked about filters and validators, right?</p>

<pre><code>class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition-&#62;addField(new StringField(&#39;username&#39;, true, null, true))
            -&#62;addValidator(new UniqueUserValidator())
            -&#62;addFilter(new LowercaseFilter())
            -&#62;addValidator(new RegexValidator(&#39;/^[a-z]+$/&#39;));
    }
}
</code></pre>

	<p>Definition::addField() returns the passed field object to allow adding validators and filters. What works for validators and filters, should work for the rest too, shouldn&#8217;t it?</p>

<pre><code>class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition-&#62;addField(new StringField(&#39;username&#39;))
            -&#62;setRequired(true)
            -&#62;setReadonly(true);
    }
}
</code></pre>

	<p>I admit, a bit more code to write, but a huge improvement in readability and therefore in maintainability. Other variants, where setter are not a good solution is to create an <strong>expressive factory</strong>. We e.g. have a Criteria object that creates and orders Criterion objects internally. Because we don&#8217;t have a fluent constructor, we have a static create-method for the Criteria object.</p>

<pre><code>$criteria = Criteria::create(&#39;User&#39;)-&#62;field(&#39;id&#39;)-&#62;equal(1);
</code></pre>

	<p>The alternative with just utilizing the constructor would be horribly to read and would have limitations regarding the parameter parsing capabilities (except if func_get_args() is used, which is totally the opposite of the paradigm of strict APIs). But back to the constructor only example:</p>

<pre><code>$criteria = new Criteria(&#39;User&#39;, array(&#39;id&#39; =&#62; 1));
</code></pre>

	<p>And how would you express &#8220;id not equal 1&#8221; with it? So that&#8217;s where <strong>expressive factories</strong> are an alternative.</p>

	<p>Constructors, as like any other method, should have as less parameters as possible but as much as needed. Obvious. The constructor should only allow setting <strong>vital information</strong> for the object (if the object has a name, there is a good chance, that the name is the parameter of the class&#8217; constructor because it is considered vital). And the <strong>ease of use</strong> depends heavily whether the parameters passed can be <strong>intuitively distinguished</strong> by looking at there values. As well when the code is written first time as for maintaining it for the rest of your life.</p>

	<p>(There are a bunch of other tricks to make parameters more readable, like using class constants as parameters, but this is out of scope of this article).</p> 
            </div>
        </content>
        <dc:subject>Design</dc:subject>
<dc:subject>Patterns</dc:subject>
<dc:subject>PHP</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/895-Still-a-dog.html" rel="alternate" title="Still a dog" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-07-16T12:06:31Z</published>
        <updated>2008-07-16T12:06:31Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=895</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=895</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/895-guid.html</id>
        <title type="html">Still a dog</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<blockquote>
		<p>But the fact remains: even if no one knows you&#8217;re a dog, you&#8217;re still a dog. A fantastical online identity never impresses readers. Instead, it makes them think you&#8217;re more into image than substance, or that you&#8217;re simply insecure. Use your real name for all interactions, or if for some reason you require anonymity, then make up a name that sounds like a perfectly normal real name, and use it consistently.<br />
<a href="http://producingoss.com/en/communications.html">Producing <span class="caps">OSS</span> &#8211; Communications</a></p>
	</blockquote> 
            </div>
        </content>
        <dc:subject>Free Software</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/894-Jabber-for-portage-0.0.5.1.html" rel="alternate" title="Jabber for portage 0.0.5(.1)" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-07-05T09:43:54Z</published>
        <updated>2008-07-10T12:03:27Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=894</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=894</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/894-guid.html</id>
        <title type="html">Jabber for portage 0.0.5(.1)</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>portage-mod_jabber is a small elog module for Gentoo’s portage which provides <acronym title="Open source instant messaging protocoll">Jabber</acronym> notification for portage. It basically allows to receive notifications via jabber when elog events occur.</p>

	<p>The new version of portage-mod_jabber fixes a deprecation warning with portage 2.2 (but works with older versions too) and introduces a new syntax for the JABBERFROM-variable: both <strong>node:pw@host.com/resource</strong> and <strong>node@host.com/resource:pw</strong> are allowed now.</p>

	<p><a href="http://software.usrportage.de/portage-mod_jabber/">Grab it while it&#8217;s hot!</a></p>

	<p><b>Note:</b> I&#8217;ve released 0.0.5.1 to fix an invalid exception catch. Catched LoadError instead of ImportError. That&#8217;s what happens when you confuse Python with Ruby.</p> 
            </div>
        </content>
        <dc:subject>Gentoo</dc:subject>
<dc:subject>Jabber</dc:subject>
<dc:subject>Portage</dc:subject>
<dc:subject>Software</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/893-Over-abbreviated.html" rel="alternate" title="Over abbreviated" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-06-30T15:23:45Z</published>
        <updated>2008-06-30T15:23:45Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=893</wfw:comment>
    
        <slash:comments>10</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=893</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/893-guid.html</id>
        <title type="html">Over abbreviated</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p><img src="http://usrportage.de/uploads/no-name.jpg" alt=""  /><br />
<a href="http://flickr.com/photos/giantginkgo/37740313/">© Giant Ginkgo</a></p>

	<p>Matthew Weier O&#8217;Phinney <a href="http://weierophinney.net/matthew/archives/181-Migrating-OOP-Libraries-and-Frameworks-to-PHP-5.3.html">announced</a> Zend&#8217;s naming scheme for the Zend Framework from the point where <span class="caps">PHP</span> 5.3 namespaces are used. The issue is, that the <span class="caps">PHP</span> parser does not allow <strong>class Abstract</strong>, neither <strong>interface Interface</strong> as both &#8220;abstract&#8221; and &#8220;interface&#8221; are reserved keywords. So Zend suggests prefixing interfaces with &#8220;I&#8221; and abstract classes with &#8220;A&#8221;. Hungarian notation for classes and interfaces.</p>

	<p>One of the bullet points in the list of &#8220;what makes a name a good name?&#8221; is and will be forever &#8220;as short as possible, as verbose as needed&#8221;, other points are &#8220;you must understand the name without studying specific rules before&#8221;. The last is why <a href="http://en.wikipedia.org/wiki/Hungarian_notation">hungarian notation</a> sucks so tremendously. The IFoo/ABar violates two of those criteria: first it is not as verbose as it could be with just a few keystrokes more: <strong>AbstractBar</strong> would work fine and is much clearer. At second it introduces a special notation you have to grasp before. While <strong>AbstractBar</strong> would be as descripive as possible, <strong>ABar</strong> is cryptic for those who are not lucky enough to practice Python programming.</p>

	<p>If we are at it, the scheme makes it impossible to have grammatically correct names: <strong>IFoo</strong> would be read as <strong>InterfaceFoo</strong> which really should be <strong>FooInterface</strong>. And no, the fix is not <strong>FooI</strong>.</p> 
            </div>
        </content>
        <dc:subject>PHP</dc:subject>
<dc:subject>Zend</dc:subject>
<dc:subject>Zend Framework</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/892-Sound-on-a-3rd-generation-MacBook.html" rel="alternate" title="Sound on a 3rd generation MacBook" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-06-10T06:17:53Z</published>
        <updated>2008-06-10T06:35:44Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=892</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=892</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/892-guid.html</id>
        <title type="html">Sound on a 3rd generation MacBook</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>Thanks to the heros on the <a href="http://www.mactel-linux.org/">Mactel</a> list I have sound again. If you use Linux on a MacBook of the third generation and your soundcard has been detected but just no sound will come out, putting the following in <b>/etc/modprobe.conf</b> (on Gentoo: <b>/etc/modprobe.d/alsa</b> and <b>modules-update</b> afterwards) should fix the problem. Please reboot or reload <strong>snd-hda-intel</strong> after changing the configuration. <b>NOTE</b>: it has been reported to work fine on MacBook Pro&#8217;s too.</p>

<pre><code>options snd-hda-intel index=0 model=mbp3
</code></pre>

 
            </div>
        </content>
        <dc:subject>Alsa</dc:subject>
<dc:subject>Gentoo</dc:subject>
<dc:subject>Kernel</dc:subject>
<dc:subject>Linux</dc:subject>
<dc:subject>MacBook</dc:subject>
<dc:subject>Mactel</dc:subject>
<dc:subject>Sound</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/891-Join-us.html" rel="alternate" title="Join us" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-06-04T14:57:15Z</published>
        <updated>2008-06-05T12:11:18Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=891</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=891</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/891-guid.html</id>
        <title type="html">Join us</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p><img src="http://usrportage.de/uploads/mv-logo.png" alt=""  /><br />
You were a bit bored lately: you wanted to have time and infrastructure for unit tests and continuous integration but it was &#8220;too expensive&#8221;, you wanted a more grown up, professional structure for development, a coding style, a build system, lots of books for training, augmentative thinking about architecture and object orientation or &#8211; more general &#8211; work you can both take pride in and sleep well with. This is how <a href="http://mediaventures.de">we</a> want to develop software (and we are close to it and continuously improving). We are offering two positions: <a href="http://mediaventures.de/index.php?id=senior-softwareentwickler-php">senior developer</a> and <a href="http://mediaventures.de/index.php?id=softwareentwickler-php">another one</a> more suited for career starters.<br />
You will work on various projects, including a not yet released open source framework based on the Zend Framework (and yes, we are using <span class="caps">PHP</span> 5.3 for development). You should be fluent in <span class="caps">PHP</span> 5, at least know what unit tests are and you have a good understanding of object oriented programming. And no, you don&#8217;t need to know who&#8217;s invented the pepper mill or the handcar or <span class="caps">PHP</span>.<br />
Additionally benefits include table football, a Wii, free water and coffee and silent workplaces. <br />
So the ball&#8217;s in your court: if you are interested, drop me a <a href="http://usrportage.de/imprint">message</a>.</p> 
            </div>
        </content>
        <dc:subject>Media Ventures GmbH</dc:subject>
<dc:subject>PHP</dc:subject>
<dc:subject>Zend Framework</dc:subject>

    </entry>
    <entry>
        <link href="http://usrportage.de/archives/888-Security-to-go.html" rel="alternate" title="Security &quot;to go&quot;?" />
        <author>
            <name>Lars Strojny</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2008-05-20T19:31:01Z</published>
        <updated>2008-05-24T21:18:40Z</updated>
        <wfw:comment>http://usrportage.de/wfwcomment.php?cid=888</wfw:comment>
    
        <slash:comments>5</slash:comments>
        <wfw:commentRss>http://usrportage.de/rss.php?version=atom1.0&amp;type=comments&amp;cid=888</wfw:commentRss>
    
    
        <id>http://usrportage.de/archives/888-guid.html</id>
        <title type="html">Security &quot;to go&quot;?</title>
        <content type="xhtml" xml:base="http://usrportage.de/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                	<p>I&#8217;m a huge fan of <a href="http://php-ids.org/">PHP-IDS</a>. Mario Heiderich and Christian Matthies did an incredible job polishing this tool, adding new features and trying to catch every esoteric attack signature. However I have the feeling there is some <a href="http://ilovephp.de/sicherheit-ganz-einfach">confusion</a> (german) about what intrusion detection is for. On a server, intrusion detection is used to diagnose a break in. First of all you do everything not to let your server go down. You have a firewall, you try not to expose services to the outside, you do <span class="caps">SSH</span> with port knocking, you put a risky service into jail or chroots, you use the Suhosin patchset and so on. There are various strategies how to harden a server. The hardening is the barrier against break-in attempts.<br />
If the hell freezes, the intrusion detection mechanism comes into play to make sure the attempt is not overseen and the machine does not become yet another zombie in a bot net. <span class="caps">PHP-IDS</span> is an intrusion detection tool on the application level. Application firewalls know about a certain protocol and its structure (e.g. <span class="caps">HTTP</span>) and inspect the protocol to detect attack patterns. Some of them are even capable of learning from usual request signatures and enforcing rules based on the learned data. There are various commercial products to achieve application firewalling. <span class="caps">PHP-IDS</span> does the same for free and sits directly on the webserver in the scope of the application. For personal usage or projects with a lower budgets who can&#8217;t effort expensive products, it might be a good supplement. Beside being a supplement, application firewalls are a valid use when security becomes an urgent problem: a lot of heavily flawed software is designed (often it is not even designed) and developed without a developer even heard about security: &#8220;Yes you can inject <span class="caps"><acronym title="HyperText Markup Language">HTML</acronym></span>, that&#8217;s a feature!&#8221;, &#8220;<strong>&#8216; OR true/</strong>* lists you every item, isn&#8217;t that cool?&#8221;. If such projects become popular, application firewalls might be an option to hotfix the disaster. But nevertheless the application needs to be fixed.<br />
The very immanent issue with application firewalls is that there is no other place to know exactly what&#8217;s proper incoming data for the application &#8211; except in the application itself. That&#8217;s why application firewalls can never be perfect. <span class="caps">IDS</span> is needed for the 2% the developer forgot. So it is not like coffee to go. It is like having the coffee and adding milk or sugar. Having milk without coffee seems pointless to me anyway.</p> 
            </div>
        </content>
        <dc:subject>PHP</dc:subject>
<dc:subject>PHPIDS</dc:subject>
<dc:subject>Security</dc:subject>
<dc:subject>Websecurity</dc:subject>

    </entry>

</feed>