<?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"
	>

<channel>
	<title>Paint the Tiger, Carve the Swan</title>
	<atom:link href="http://schinckel.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://schinckel.net</link>
	<description>Like a fortune cookie, only without the fortune, and not a cookie.</description>
	<pubDate>Wed, 23 Dec 2009 13:46:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
	<language>en</language>
			<item>
		<title>View man pages in Preview</title>
		<link>http://schinckel.net/2009/12/23/view-man-pages-in-preview/</link>
		<comments>http://schinckel.net/2009/12/23/view-man-pages-in-preview/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 13:46:01 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[MacOS X]]></category>

		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/12/23/view-man-pages-in-preview/</guid>
		<description><![CDATA[It&#8217;s not a new concept, but here is my take on it:

function man {
    # We can get the actual path to the man command here, so we can override
    # it with our function name.
    MAN=`which man`
    # Change these two if [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not a new concept, but here is my take on it:</p>
<div class="highlight">
<pre><span class="k">function </span>man <span class="o">{</span>
    <span class="c"># We can get the actual path to the man command here, so we can override</span>
    <span class="c"># it with our function name.</span>
    <span class="nv">MAN</span><span class="o">=</span><span class="sb">`</span>which man<span class="sb">`</span>
    <span class="c"># Change these two if you are not on OS X.</span>
    <span class="nv">CACHE_DIR</span><span class="o">=</span><span class="s2">&quot;${HOME}/Library/Caches/manpages&quot;</span>
    <span class="nv">OPEN</span><span class="o">=</span><span class="s2">&quot;open&quot;</span>

    <span class="c"># If we don&#39;t have any arguments, use the nice man error message</span>
    <span class="k">if</span> <span class="o">[</span> ! <span class="nv">$1</span> <span class="o">]</span>; <span class="k">then</span>
        <span class="nv">$MAN</span>
        <span class="k">return</span>
<span class="k">    fi</span>

    <span class="c"># If we have an argument that clashes with what we are wanting to be</span>
    <span class="c"># able to do, pass the whole command through.</span>
    <span class="k">for </span>ARG in <span class="nv">$*</span>; <span class="k">do</span>
<span class="k">        case</span> <span class="nv">$ARG</span> in
            -<span class="o">[</span>dfkKwtWP<span class="o">])</span>
                <span class="nv">$MAN</span> <span class="nv">$*</span>
                <span class="k">return</span>;;
        <span class="k">esac</span>
<span class="k">    done</span>

    <span class="c"># Make sure our cache directory exists.</span>
    mkdir -p <span class="nv">$CACHE_DIR</span>
    <span class="c"># Get the man page(s) that match our query.</span>
    <span class="nv">MAN_FILES</span><span class="o">=</span><span class="sb">`</span><span class="nv">$MAN</span> -w <span class="nv">$*</span><span class="sb">`</span>
    <span class="k">for </span>MAN_FILE in <span class="nv">$MAN_FILES</span>; <span class="k">do</span>
        <span class="c"># Get the name of the man file, and the section.</span>
        <span class="nv">MAN_PAGE</span><span class="o">=</span><span class="sb">`</span>basename <span class="s2">&quot;$MAN_FILE&quot;</span> | cut -d <span class="se">\.</span> -f 1-2 | sed <span class="s1">&#39;s/\./(/&#39;</span> | sed <span class="s1">&#39;s/$/)/&#39;</span><span class="sb">`</span>
        <span class="c"># Our PDF will be in this location</span>
        <span class="nv">PDF_FILE</span><span class="o">=</span><span class="s2">&quot;${CACHE_DIR}/${MAN_PAGE}&quot;</span>

        <span class="c"># If we actually have a man file that matches</span>
        <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&quot;$MAN_FILE&quot;</span> <span class="o">]</span>; <span class="k">then</span>
            <span class="c"># See if the man file is newer than our cached PDF, and if it is,</span>
            <span class="c"># then generate a new PDF. This works even if $PDF_FILE does not</span>
            <span class="c"># exist.</span>
            <span class="k">if</span> <span class="o">[</span> <span class="nv">$MAN_FILE</span> -nt <span class="nv">$PDF_FILE</span> <span class="o">]</span>; <span class="k">then</span>
                <span class="nv">$MAN</span> -t <span class="nv">$*</span> | pstopdf -i -o <span class="s2">&quot;$PDF_FILE&quot;</span>
            <span class="k">fi</span>
            <span class="c"># Then display the file.</span>
            <span class="nv">$OPEN</span> <span class="s2">&quot;$PDF_FILE&quot;</span>
        <span class="k">fi</span>
<span class="k">    done</span>
<span class="o">}</span>
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/12/23/view-man-pages-in-preview/feed/</wfw:commentRss>
		</item>
		<item>
		<title>On UI sins</title>
		<link>http://schinckel.net/2009/11/14/on-ui-sins/</link>
		<comments>http://schinckel.net/2009/11/14/on-ui-sins/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 22:53:52 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Software]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/11/14/on-ui-sins/</guid>
		<description><![CDATA[My sister likes to back up DVDs that her children use all of the time: they are old enough to change discs, but they tend to get scratched. So, I have been looking into backup solutions for her to use on her new MacBook.
I came across Aimersoft DVD Backup, and ran it. Not looking too [...]]]></description>
			<content:encoded><![CDATA[<p>My sister likes to back up DVDs that her children use all of the time: they are old enough to change discs, but they tend to get scratched. So, I have been looking into backup solutions for her to use on her new MacBook.</p>
<p>I came across Aimersoft DVD Backup, and ran it. Not looking too bad to begin with.</p>
<p><img src="http://schinckel.net/images/Register.png" /></p>
<p>The actual window, however, is appalling:</p>
<p><img src="http://schinckel.net/images/Aimersoft%20DVD%20Backup(Unregistered).png" alt="Aimersoft DVD Backup(Unregistered)" /></p>
<p>It is a little hard to see, but the window is not actually connected to the titlebar. You can actually see the objects that are in obscured windows in the gap between them!</p>
<p>Finally, the text from the close confirmation sheet just cracked me up:</p>
<p><img src="http://schinckel.net/images/AimersoftCloseSheet.png" /></p>
<p>Surely, they can tell if a copying task is in progress, and display a dialog then. If not, then just quit immediately!</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/11/14/on-ui-sins/feed/</wfw:commentRss>
		</item>
		<item>
		<title>On Django and Check Constraints</title>
		<link>http://schinckel.net/2009/09/25/on-django-and-check-constraints/</link>
		<comments>http://schinckel.net/2009/09/25/on-django-and-check-constraints/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 09:15:38 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Database]]></category>

		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/09/25/on-django-and-check-constraints/</guid>
		<description><![CDATA[I&#8217;ve come to love Django, and now I seem to be spending not only my work time, but also my own time working on one django project or another. Today at work I came across the need to have check constraints in a database. For instance, this can be used to ensure that the start [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve come to love Django, and now I seem to be spending not only my work time, but also my own time working on one django project or another. Today at work I came across the need to have check constraints in a database. For instance, this can be used to ensure that the start of an event is before the end of the event, or that a certain value has a particular range of values.</p>
<p>For the SQL savvy, it can look like:</p>
<p><span style="font-family: monospace;">CREATE TABLE event (<br />
&#8230;more columns here&#8230;<br />
start datetime,<br />
finish datetime,<br />
count integer CHECK (count &gt;= 0),<br />
<span style="font-family: Helvetica;"><span style="font-family: monospace;">CONSTRAINT event_starts_before_finish CHECK (start &lt; finish)<br />
<span style="font-family: Helvetica;"><span style="font-family: monospace;">);</span></span></span></span></span></p>
<p>There are two types of constraint here: the column-level constraint, which in this instance can be done with django, and the table-level constraint, which in many systems cannot be a part of a column definition. In PostgreSQL, my DBMS of choice, it is possible to define a constraint that affects more than one column as part of a column, but I prefer not to. Note also that I am using the syntax form that allows me to name the constraint. This means I can alter or drop it later.</p>
<p>As I mentioned, django can do the first type of constraint, as long as it is a &gt; 0 constraint, using one of the field types that subclasses PositiveInteger. However, there is no functionality built into django to do the latter. And I would like to use them.</p>
<p>It is possible to just add the constraints to an already existing database: indeed, that is what I did for work. Having the constraints at the database level means that, since I have more than one interface to my datastore (don&#8217;t ask: one of them is for an old SOAP interface I need to keep around), I want to ensure that even if someone accesses it outside of django, they cannot put in data that breaks these constraints. Similarly, if I use an interface other than the admin interface, or heaven forbid, open up the database in raw form, I cannot accidentally put in data that breaks this validation.</p>
<p>But, pure database level constraints don&#8217;t give very nice feedback in django. It is nicer to have the pretty red boxes around my field than the traceback. So, I want the validation to occur on the field level as well. As long as I am using django&#8217;s forms (and my API for RESTful access will use them for validation), then I will have these errors nicely presented.</p>
<p>So, to that end, I have created some code that allows for the definition and enforcement of both of these types of constraint.</p>
<p>The column form allows for a new keyword argument to a field:</p>
<p><code>count = models.IntegerField(constraint="&gt;= 0")</code></p>
<p>Notably, the string that can be passed in must conform to the pattern &#8220;cmp value&#8221;, where cmp is one of the comparison operators (&lt;, &gt;, &lt;=, &gt;=, =, !=), and value is a valid value for this column type. It will be passed to the to_python() method of this field when comparing. There must be a string between the two parts.</p>
<p>The other form is a new attribute on the Meta class of a model.</p>
<p><span style="font-family: monospace;">check_constraints = (&#8217;start &lt; finish&#8217;,)</span>&nbsp;&nbsp;</p>
<p>This must be a tuple of strings, where a string is of the form &#8220;column cmp column&#8221;. Again, there must be a space either side of cmp, and each column name must be a valid column. Not meeting these criteria will result in a validation error.</p>
<p>From these definitions, the database constraints will be applied, and validation of forms will also occur.</p>
<p>I have deliberately made the constraints simple (ie, not callable objects) so that they can easily be converted to database constraints. For instance, they can effectively be transferred straight through to the database (with the addition of the column name in the case of the column constraint).</p>
<p>I am going to create a ticket in the django trac, and submit a patch. Guessing I should write up some test cases, though!</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/09/25/on-django-and-check-constraints/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Setup Django with Passenger Prefpane</title>
		<link>http://schinckel.net/2009/07/25/setup-django-with-passenger-prefpane/</link>
		<comments>http://schinckel.net/2009/07/25/setup-django-with-passenger-prefpane/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 04:26:59 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[apache]]></category>

		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/07/25/setup-django-with-passenger-prefpane/</guid>
		<description><![CDATA[I am loving Django for web development. I didn&#8217;t have it set up to serve my (development) projects automatically until just now.
I had installed the Passenger Prefpane, which greatly simplifies the management of VirtualHost-based serving of sites, at least for Rails and other ruby-based frameworks. With a little work, you can use the same setup [...]]]></description>
			<content:encoded><![CDATA[<p>I am loving <a href="http://djangoproject.com">Django</a> for web development. I didn&#8217;t have it set up to serve my (development) projects automatically until just now.</p>
<p>I had installed the <a href="http://www.modrails.com/">Passenger</a> <a href="http://github.com/alloy/passengerpane/tree/master">Prefpane</a>, which greatly simplifies the management of VirtualHost-based serving of sites, at least for Rails and other ruby-based frameworks. With a little work, you can use the same setup to serve Django projects.</p>
<p>Rather than re-detail the setup, I&#8217;ll just point you to the <a href="http://www.modrails.com/">mod_passenger setup</a>, and the <a href="http://www.fngtps.com/passenger-preference-pane">Passenger Prefpane setup</a> pages.</p>
<p>Now, to set up a Django project: obviously you need a django project. Create one, and note where it is located. I stick all of mine in ~/Sites.</p>
<p>Add a file to the root of this project, called passenger_wsgi.py. It needs to contain the following data:</p>
<pre>
import os, sys
sys.path.append('/Users/matt/Sites') # Replace with your directory
os.environ['DJANGO_SETTINGS_MODULE'] = 'testing.settings' # replace with your projectname.
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
</pre>
<p>Now, add the site to the Passenger prefpane. My site is the testing.local site:</p>
<p><img src="http://s3.amazonaws.com/ember/0QX55qzZXvQYU50eIrNf2Mfo03fvMzTO_m.png" /></p>
<p>Now visit the address and ensure that it works. You should get the basic &#8220;<em>you need to set up django</em>&#8221; message.</p>
<p>To get the admin media served by the standard apache setup, I created a link inside the <code>/Library/WebServer/Documents</code> directory to <code>/Library/Python/2.5/site-packages/django/contrib/admin/media</code>. This can be done inside the Terminal:</p>
<pre><code>sudo ln -s /Library/Python/2.5/site-packages/django/contrib/admin/media /Library/WebServer/Documents/admin-media/</code></pre>
<p>Then, change the <code>ADMIN_MEDIA</code> setting in your django projects to &#8220;<code>http://localhost/admin-media/</code>&#8220;. This is probably the weakest point in the setup, as it will only work for pages served to your machine, not others on your network.</p>
<pre>
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = 'http://localhost/admin-media/'
</pre>
<p>I had some issues with mod_passenger serving the data for localhost (and arne, my actual machine&#8217;s name) from the first installed VirtualHost. To overcome this, I put in a new file into /etc/apache2/other/localhost.conf, which looks like:</p>
<pre>
&lt;VirtualHost *:80&gt;
  DocumentRoot "/Library/WebServer/Documents"
  &lt;directory "/Library/WebServer/Documents"&gt;
    Order allow,deny
    Allow from all
  &lt;/directory&gt;
&lt;/VirtualHost&gt;
</pre>
<p>This forces unnamed, or other sites to work as intended. Including the <code>/User/*/Sites</code> directories.</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/07/25/setup-django-with-passenger-prefpane/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Prowl</title>
		<link>http://schinckel.net/2009/07/07/prowl/</link>
		<comments>http://schinckel.net/2009/07/07/prowl/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 12:17:02 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Growl]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/07/07/prowl/</guid>
		<description><![CDATA[Prowl is awesome. Growl notifications can be forwarded to your iPhone.
But you can get notifications from anywhere. A Perl script is included, but that didn&#8217;t work on my server. So I wrote one in Ruby:

#! /usr/bin/ruby

# A ruby class for sending notifications to Prowl.

require 'uri'
require 'net/http'
require 'net/https'

class String
  def urlencode
    gsub( [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://prowl.weks.net/">Prowl</a> is awesome. <a href="http://growl.info/">Growl</a> notifications can be forwarded to your iPhone.</p>
<p>But you can get notifications from anywhere. A Perl script is included, but that didn&#8217;t work on my server. So I wrote one in Ruby:</p>
<pre>
#! /usr/bin/ruby

# A ruby class for sending notifications to Prowl.

require 'uri'
require 'net/http'
require 'net/https'

class String
  def urlencode
    gsub( /[^a-zA-Z0-9\-_\.!~*'()]/n ) {|x| sprintf('%%%02x', x[0]) }
  end
end

class Hash
  def urlencode
    collect { |k,v| "#{k.to_s.urlencode}=#{v.to_s.urlencode}" }.join('&amp;')
  end
end

class Prowler
  def initialize user, pass
    @url = URI.parse('https://prowl.weks.net/api/add_notification.php')
    @username = user
    @password = pass

    @http = Net::HTTP.new(@url.host, @url.port)
    @http.use_ssl = true
  end

  def send_notification app, evt, desc

    options = {
      'application' =&gt; app,
      'event' =&gt; evt,
      'description' =&gt; desc
    }

    req = Net::HTTP::Get.new("#{@url.path}?#{options.urlencode}")
    req.basic_auth @username, @password
    @http.request(req)
  end

end

# How to use?
# p = Prowler.new('username', 'password')
# p.send_notification('App','Event','Desc')
</pre>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/07/07/prowl/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Logos</title>
		<link>http://schinckel.net/2009/05/24/logos/</link>
		<comments>http://schinckel.net/2009/05/24/logos/#comments</comments>
		<pubDate>Sun, 24 May 2009 02:53:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Stea]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/05/24/logos/</guid>
		<description><![CDATA[Started up a new iPhone app today. The logo at the bottom of the screen looked a bit familiar:

Here is the logo from the Adelaide City Council (which has been in use for about 7 years):

Wonder which came first&#8230;
If I overlay one one the other, we see they are not identical:

]]></description>
			<content:encoded><![CDATA[<p>Started up a new iPhone app today. The logo at the bottom of the screen looked a bit familiar:</p>
<p><img src="http://www.quicksnapper.com/files/4901/8847654464A18B5999E0B9_m.png" /></p>
<p>Here is the logo from the Adelaide City Council (which has been in use for about 7 years):</p>
<p><img src="http://www.quicksnapper.com/files/4901/18936119564A18B596AA4A3_m.png" /></p>
<p>Wonder which came first&#8230;</p>
<p>If I overlay one one the other, we see they are not identical:</p>
<p><a href="http://www.quicksnapper.com/schinckel/image/merged-logos"><img src="http://www.quicksnapper.com/files/4901/11752156844A18B7E19014E_m.png" title="Hosted by QuickSnapper.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/05/24/logos/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fix Redmine not showing repository data</title>
		<link>http://schinckel.net/2009/05/14/fix-redmine-not-showing-repository-data/</link>
		<comments>http://schinckel.net/2009/05/14/fix-redmine-not-showing-repository-data/#comments</comments>
		<pubDate>Thu, 14 May 2009 03:36:59 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/05/14/fix-redmine-not-showing-repository-data/</guid>
		<description><![CDATA[For some time, the git repository I am using to track changes for my Django-Management TextMate bundle was not working correctly in Redmine. I was able to connect it up using the settings, but was getting errors about the files not being found.
It turns out that git was not in my path. Putting a link [...]]]></description>
			<content:encoded><![CDATA[<p>For some time, the git repository I am using to track changes for my Django-Management TextMate bundle was not working correctly in Redmine. I was able to connect it up using the settings, but was getting errors about the files not being found.</p>
<p>It turns out that git was not in my path. Putting a link from /usr/local/bin/git to /usr/bin/git fixed that all up.</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/05/14/fix-redmine-not-showing-repository-data/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TextMate return codes</title>
		<link>http://schinckel.net/2009/05/05/textmate-return-codes/</link>
		<comments>http://schinckel.net/2009/05/05/textmate-return-codes/#comments</comments>
		<pubDate>Tue, 05 May 2009 08:34:26 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[TextMate]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/05/05/textmate-return-codes/</guid>
		<description><![CDATA[From the TextMate manual:

These functions only work when the initial output option is not set as &#8220;Show as HTML&#8221;. The list of functions is as follows:

exit_discard
exit_replace_text
exit_replace_document
exit_insert_text
exit_insert_snippet
exit_show_html
exit_show_tool_tip
exit_create_new_document&#160;&#160;


This is all well and good, but what about when you are in another language?
Simple. Just ensure your exit code matches. The values start at 200, for exit_discard, and 205 [...]]]></description>
			<content:encoded><![CDATA[<p>From the TextMate manual:</p>
<blockquote>
<p>These functions only work when the initial output option is not set as &#8220;Show as HTML&#8221;. The list of functions is as follows:</p>
<ul>
<li>exit_discard</li>
<li>exit_replace_text</li>
<li>exit_replace_document</li>
<li>exit_insert_text</li>
<li>exit_insert_snippet</li>
<li>exit_show_html</li>
<li>exit_show_tool_tip</li>
<li>exit_create_new_document&nbsp;&nbsp;</li>
</ul>
</blockquote>
<p>This is all well and good, but what about when you are in another language?</p>
<p>Simple. Just ensure your exit code matches. The values start at 200, for exit_discard, and 205 is exit_show_html.</p>
<p>This is probably not the best way to do it, as these may change in the future. But, I couldn&#8217;t think of another way, at least not offline.</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/05/05/textmate-return-codes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Reasons PHP sucks #753</title>
		<link>http://schinckel.net/2009/04/28/reasons-php-sucks-753/</link>
		<comments>http://schinckel.net/2009/04/28/reasons-php-sucks-753/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 10:00:57 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/04/28/reasons-php-sucks-753/</guid>
		<description><![CDATA[
Another good example of a PHP “quirk” is the way PHP handles constants. It was one of the major factors affecting performance. Just removing all the constants allowed us to improve the performance by almost 2x (we left one constant to be precise).

From The Need for Speed.
That&#8217;s right - PHP is up to 2X faster [...]]]></description>
			<content:encoded><![CDATA[<blockquote>
<p>Another good example of a PHP “quirk” is the way PHP handles constants. It was one of the major factors affecting performance. Just removing all the constants allowed us to improve the performance by almost 2x (we left one constant to be precise).</p>
</blockquote>
<p>From <a href="http://blog.openx.org/06/the-need-for-speed/">The Need for Speed</a>.</p>
<p>That&#8217;s right - PHP is up to 2X faster if you don&#8217;t use constants. You know, that means hardcode values in&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/04/28/reasons-php-sucks-753/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Patch for Mercurial.tmbundle</title>
		<link>http://schinckel.net/2009/04/27/patch-for-mercurialtmbundle/</link>
		<comments>http://schinckel.net/2009/04/27/patch-for-mercurialtmbundle/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 02:10:24 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Mercurial]]></category>

		<category><![CDATA[TextMate]]></category>

		<guid isPermaLink="false">http://schinckel.net/2009/04/27/patch-for-mercurialtmbundle/</guid>
		<description><![CDATA[
diff -r 5e13047a2284 Support/hg_commit.rb
--- a/Support/hg_commit.rb	Mon Apr 27 11:38:15 2009 +0930
+++ b/Support/hg_commit.rb	Mon Apr 27 11:39:00 2009 +0930
@@ -79,7 +79,7 @@
   commit_paths_array = matches_to_paths(commit_matches)
   commit_status = matches_to_status(commit_matches).join(&#34;:&#34;)
   commit_path_text = commit_paths_array.collect{&#124;path&#124; path.quote_filename_for_shell }.join(&#34; &#34;)
-  commit_args = %x{&#34;#{commit_tool}&#34; --status #{commit_status} #{commit_path_text} }
+  commit_args = %x{&#34;#{commit_tool}&#34; --diff-cmd hg,diff --status #{commit_status} #{commit_path_text} }

 [...]]]></description>
			<content:encoded><![CDATA[<div class="highlight">
<pre><span class="gh">diff -r 5e13047a2284 Support/hg_commit.rb</span>
<span class="gd">--- a/Support/hg_commit.rb	Mon Apr 27 11:38:15 2009 +0930</span>
<span class="gi">+++ b/Support/hg_commit.rb	Mon Apr 27 11:39:00 2009 +0930</span>
<span class="gu">@@ -79,7 +79,7 @@</span>
   commit_paths_array = matches_to_paths(commit_matches)
   commit_status = matches_to_status(commit_matches).join(&quot;:&quot;)
   commit_path_text = commit_paths_array.collect{|path| path.quote_filename_for_shell }.join(&quot; &quot;)
<span class="gd">-  commit_args = %x{&quot;#{commit_tool}&quot; --status #{commit_status} #{commit_path_text} }</span>
<span class="gi">+  commit_args = %x{&quot;#{commit_tool}&quot; --diff-cmd hg,diff --status #{commit_status} #{commit_path_text} }</span>

   status = $CHILD_STATUS
   if status != 0
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://schinckel.net/2009/04/27/patch-for-mercurialtmbundle/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
