<?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>Terminus a Quo &#187; Code and Consequences</title>
	<atom:link href="http://abing.gotdns.com/posts/category/code-and-consequences/feed/" rel="self" type="application/rss+xml" />
	<link>http://abing.gotdns.com</link>
	<description>Because you can never have too many blogs on the Internet...</description>
	<lastBuildDate>Tue, 19 May 2009 00:23:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Taking Another Stab At Learning Haskell&#8230;</title>
		<link>http://abing.gotdns.com/posts/2009/taking-another-stab-at-learning-haskell/</link>
		<comments>http://abing.gotdns.com/posts/2009/taking-another-stab-at-learning-haskell/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 10:37:34 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=286</guid>
		<description><![CDATA[I have been trying to learn functional programming in Haskell on and off for about two years now. The functional programming approach, terminologies and Haskell&#8217;s unfamiliar syntax makes me feel like a fish out of water every time I try to learn it. What makes it especially difficult for me is that the BSCS course [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I have been trying to learn functional programming in Haskell on and off for about two years now. The functional programming approach, terminologies and Haskell&#8217;s unfamiliar syntax makes me feel like a fish out of water every time I try to learn it. What makes it especially difficult for me is that the BSCS course I took did not have a functional programming subject plus the fact that I a mostly self-taught. I first learned to program using Atari Basic and 6502 assembly language. From then I learned C, Pascal, C++, Java, PHP, Perl, Python, and a slew of other esoteric languages. I also know CLISP and ELISP so I have some familiarity with functional programming. One thing that all these languages had in common is that they are all procedural, imperative programming languages. I have been conditioned into the mindset that a computer program is <em>a series of instructions</em> given to a computer. Learning functional programming and, at its heart, lambda calculus throws most of what I know about programming out the window. You are forced to think differently. Programs are no longer a series of instructions. They are now special applications of fundamental and advanced mathematical concepts.</p>

<p>Most of the material I have been reading so far introduces concepts which are completely foreign to me using terms that I have never even heard before (&#8221;monad&#8221;, hyukhyuk!). Some materials like <a href="http://www.haskell.org/~pairwise/intro/intro.html" title="Haskell Tutorial for C Programmers">&#8220;Haskell Tutorial for C Programmers&#8221;</a> attempts to map functional programming concepts in Haskell to imperative programming concepts in C. That was my last attempt to learn Haskell prior to this current one. It starts off slow but in the next chapter it gets deep all of a sudden and I felt lost and eventually gave up.</p>

<p>The approach taken by &#8220;Haskell Tutorial for C Programmers&#8221; is essentially the same approach that I had taken to learn <strong>all</strong> the programming languages that I know. This approach consists of three stages:</p>

<ol>
<li>Learn about all the keywords of the new language, then map them to the keywords of a language that you already know.</li>
<li>Learn how to do all the concepts using the new language like loops, branching, function definition, etc.</li>
<li>Finally, learn how to do advanced I/O like reading/writing files and talking to a network.</li>
</ol>

<p>This approach has not failed me until I tried to learn functional programming using Haskell. I eventually gave up until better material was available and I had some spare time. I have been especially productive using Django and Python lately so I have been finding a bit of time and with a new <a href="http://book.realworldhaskell.org/read/" title="Real World Haskell">book on Haskell available for free</a>, I decided to give it another shot.</p>

<p>I am reading well into chapter 3 as I write this and so far, my brain is still chugging along nicely. I took a completely different approach to learning this time: Zen Mind, Beginner&#8217;s Mind. It is at the core of the teachings of Shunryu Suzuki-roshi. Basically it means emptying your mind of all preconceived notions and being free from expectations of what should and shouldn&#8217;t be. In this mental state, all you do is explore and observe.</p>

<p>The approach is working thus far. However it would not be possible if &#8220;Real World Haskell&#8221; itself was written in the same cut-and-dry approach like that found in most of the books on Haskell that I have read. The book takes on a very nice pace in the first 2 chapters so far. It introduces functional programming concepts using small, working, real-world examples. It exposes only as much of the language as it needs to and explains everything in detail without overwhelming you. Considering the depth of the subject, it looks like an excellent book written in a very engaging manner.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2009/taking-another-stab-at-learning-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django File Upload Handling Examples</title>
		<link>http://abing.gotdns.com/posts/2009/django-file-upload-handling-examples/</link>
		<comments>http://abing.gotdns.com/posts/2009/django-file-upload-handling-examples/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 05:10:24 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=257</guid>
		<description><![CDATA[I have been working on a multi-user blogging and publishing platform using Django 1.0 lately. Naturally this requires the backend to be able to handle file uploads. A lot of things have changed from Django 0.96 which I am still using on some legacy code. One of those changes is the way Django 1.0 handles [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I have been working on a multi-user blogging and publishing platform using <a href="http://www.djangoproject.com/">Django 1.0</a> lately. Naturally this requires the backend to be able to handle file uploads. A lot of things have changed from Django 0.96 which I am still using on some legacy code. One of those changes is the way Django 1.0 handles file uploads. Most of the changes done were made to allow Django apps to handle large files without soaking up too much memory.</p>

<p>So what has changed? The most visible change is that there are now at least two separate API&#8217;s that you have to work with. You have the <a href="http://docs.djangoproject.com/en/dev/ref/files/file/#ref-files-file">File API</a> and the <a href="http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage">Storage API</a>. The File API which exposes the <code>File</code> class provides a thin wrapper around <a href="http://www.python.org/">Python</a> <code>file</code> objects. The Storage API, on the other hand, exposes a base class <code>Storage</code> that you can use to implement custom storage facilities. There is another API that provides <a href="http://docs.djangoproject.com/en/dev/topics/http/file-uploads/#writing-custom-upload-handlers">FileUploadHandler</a>. This will allow you to customize the way Django handles the uploaded files in their &#8220;raw&#8221; form. For most purposes, the <code>File</code> and <code>Storage</code> API will suffice.</p>

<p>This post is meant to supplement the information found in the <a href="http://docs.djangoproject.com/en/dev/topics/http/file-uploads/#topics-http-file-uploads">&#8220;Handling Uploaded Files&#8221;</a> section of the Django File Uploads documentation. You will still need to refer to documentation.</p>

<p><span id="more-257"></span></p>

<p>The examples I will be using here implement basic file uploads handling in Django 1.0. The examples provided in the official Django documentation, as of 18 Feb 2009, do not give you an idea of how the <code>File</code> and <code>Storage</code> can be used together. Please note that these examples <strong>will not work with Django versions before 1.0</strong>.</p>

<h3>The Model</h3>

<p>Here is the model that we will be using for this example:</p>

<pre class="brush: python">

from django.db import models

class Attachment(models.Model):
    attached_file = models.FileField(upload_to=&#039;attachments&#039;)
    mimetype = models.CharField(max_length=64, editable=False)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, auto_now_add=True, editable=False)

</pre>

<p>We have marked the 3 fields that are not editable so that the corresponding form fields will not be created for them by Django&#8217;s automatic admin and <code>django.forms.ModelForm</code>.</p>

<h3>The Form</h3>

<p>Normally you would just use <code>django.forms.ModelForm</code> to create the form. Like so:</p>

<pre class="brush: python">

from django.forms import ModelForm

class AttachmentForm(ModelForm):
    class Meta:
        model = Attachment

</pre>

<p>This will take care of most use-cases where you have a simple app with one form per model. Taking it a bit further, you could just make use of Django 1.0&#8217;s excellent <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/#ref-contrib-admin">&#8220;automatic admin interface&#8221;</a>. This is what you <strong>should</strong> normally do when you are just starting out with Django. However, there are times when you just want a bit more control over the way things are done. In this context, we will create a form class manually to illustrate how you would use Django&#8217;s <code>File</code> and <code>Storage</code> API.</p>

<pre class="brush: python">

from django import forms

class AttachmentForm(forms.Form):
    attached_file = forms.FileField()

    def __init__(self, bound_object=None, *args, **kwargs):
        super(AttachmentForm, self).__init__(*args, **kwargs)
        self.bound_object = bound_object
        self.is_updating = False
        if self.bound_object:
            self.is_updating = True

    def save(self):
        if not self.is_updating:
            self.bound_object = Attachment()
        # Retrieve the UploadedFile object for the attached_file field.
        uploaded_file = self.cleaned_data[&#039;attached_file&#039;]
        # Clean up the filename before storing it.
        import re
        stored_name = re.sub(r&#039;[^a-zA-Z0-9._]+&#039;, &#039;-&#039;, uploaded_file.name)
        # Save the file and its metadata.
        self.bound_object.attached_file.save(stored_name, uploaded_file)
        self.bound_object.mimetype = uploaded_file.content_type

</pre>

<p>In the example above, we used the <code>save()</code> method of the <code>Attachment</code> object&#8217;s <code>attached_file</code> field. The <code>save()</code> method&#8217;s second argument takes any object that implements the <code>File</code> class&#8217; methods. All file uploads handled by Django&#8217;s default upload handlers are <code>UploadedFile</code> objects. Since <code>UploadedFile</code> is a subclass of <code>File</code> we can use it directly in the <code>save()</code> method of our file field.</p>

<p>By default the uploaded file will be saved on the file system under the directory structure specified by <code>settings.MEDIA_ROOT</code> plus the <code>upload_to</code>. So if you have <code>settings.MEDIA_ROOT</code> set to <code>/webapp/media_root</code> adding our <code>upload_to</code> setting for the model above, the file for <code>attached_file</code> will be saved under the directory <code>/webapp/media_root/attached_file</code>. Normally this directory will also be mapped to the appropriate public URL on your webserver&#8217;s configuration.</p>

<p>There are times however when you want to change the default storage behavior. This is where the <code>Storage</code> API comes in. For example we want to be able to save files in a different root directory. The problem is that you can only specify one <code>settings.MEDIA_ROOT</code> for your entire app. To do this, we need to pass the parameter <code>storage</code> to our <code>attached_file</code> field.</p>

<p>Here is our model again, this time we specify a custom storage location other than MEDIA_ROOT.</p>

<pre class="brush: python">

from django.core.files.storage import FileSystemStorage
from django.db import models

attachment_file_storage = FileSystemStorage(location=&#039;/webapp/attachments_root&#039;, base_url=&#039;/attachments&#039;)

class Attachment(models.Model):
    attached_file = models.FileField(upload_to=&#039;attachments&#039;, storage=attached_file_storage)
    mimetype = models.CharField(max_length=64, editable=False)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    updated = models.DateTimeField(auto_now=True, auto_now_add=True, editable=False)

</pre>

<p>With our modified model, calling the <code>save()</code> method of the <code>attached_file</code> field will save the file under <code>/webapp/attachments_root/attachments</code>.</p>

<p>It does not end with customizing storage locations on the filesystem however. With the <code>Storage</code> API you can customize how files are actually saved by creating a subclass of <code>Storage</code> that overrides the appropriate API methods as documented <a title="Django Storage API" href="http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage">here</a> and <a title="Django Custom File Storage" href="http://docs.djangoproject.com/en/dev/howto/custom-file-storage/#howto-custom-file-storage">here</a>.</p>

<h3>Django FileUploadHandler API</h3>

<p>By default Django 1.0 handles file uploads using either <code>django.core.files.uploadhandler.TemporaryFileUploadHandler</code> or <code>django.core.files.uploadhandler.MemoryFileUploadHandler</code>. <code>TemporaryFileUploadHandler</code> is the default for files larger than <code>settings.FILE_UPLOAD_MAX_MEMORY_SIZE</code>. This handler streams the uploaded file to a temporary file saved under <code>settings.FILE_UPLOAD_TEMP_DIR</code>. It then wraps this file with a <code>TemporaryUploadFile</code> object. For smaller files, Django uses the <code>MemoryUploadFileHandler</code>. This handler wraps the uploaded file with a <code>StringIO</code> object. Either way, you get an object with a <code>file</code>-like interface. The only difference is where the file&#8217;s data is actually stored.</p>

<p>The <code>FileUploadHandler</code> allows you to customize the default behavior by using subclasses of <code>FileUploadHandler</code> and inserting them into the <code>settings.FILE_UPLOAD_HANDLERS</code> list. This is documented in the <a href="http://docs.djangoproject.com/en/dev/topics/http/file-uploads/#upload-handlers">&#8220;Upload Handlers&#8221;</a> section of the Django manual.</p>

<h3>Performing Additional Processing</h3>

<p>There are cases when you need to do more than just save an uploaded file. For instance, in a photo album application, you might want to use <a title="Python Imaging Library" href="http://www.pythonware.com/products/pil/">PIL</a> to resize uploaded images or create thumbnails before you save them. In the examples above, we did not do any post-processing of the uploaded files and just saved them right away. It really depends on what you intend to do with the uploaded file. The most common way is to just read the file into a variable using the <code>read()</code> method. You must be careful when you do this however since you will overload your server if the uploaded file is too large. Use the <code>size</code> propery of the <code>File</code> object to test if a file is too large for your system to handle. You would normally do this in your form&#8217;s <code>clean()</code> method.</p>

<p>A more efficient way of applying post-processing is to stream the file and do it lazily. PIL&#8217;s <code>Image.open()</code> is a good example. Using PIL as an example, here is how you would apply post-processing to uploaded images. This example also shows how to use <code>ContentFile</code>.</p>

<pre class="brush: python">

from PIL import Image

def postprocess_image(uploaded_file):
    img = Image.open(uploaded_file)
    # ... do image post-processing and manipulation ...
    return img

</pre>

<p>Elsewhere, in one of your form&#8217;s methods (implemented with <code>self.bound_object</code> as the example above)&#8230;</p>

<pre class="brush: python">

def save_uploaded_photo(self):
    uploaded_image = self.cleaned_data[&#039;uploaded_image&#039;]
    # We assume that uploaded_image.size has been checked in
    # the form&#039;s clean() method and that we are good to go.
    img = postprocess_image(uploaded_image)
    if (img.format == &#039;JPEG&#039;):
        processed_image = ContentFile(img.tostring(&#039;jpeg&#039;, img.mode))
    elif (img.format == &#039;PNG&#039;):
        # PIL Image.tostring() does not support PNG encoding for some reason.
        imgstr = StringIO()
        img.save(imgstr, &#039;PNG&#039;)
        imgstr.reset()
        processed_image = ContentFile(imgstr.read())
    elif (img.format == &#039;GIF&#039;):
        processed_image = ContentFile(img.tostring(&#039;gif&#039;, img.mode))

    # Clean up the filename before storing it.
    import re
    stored_name = re.sub(r&#039;[^a-zA-Z0-9._]+&#039;, &#039;-&#039;, uploaded_image.name)
    self.bound_object.image.save(stored_name, processed_image)

</pre>

<p>The above code is overly simplified and does not perform any additional checking of the file data or any exception handling. Do note that in the versions of PIL I am using, <code>Image.tostring()</code> does not support PNG encoding. This is why some additional code was needed.</p>

<p>At first glance, it may be a bit overwhelming. But the new API allows for greater flexibility in handling file uploads. It allows you to implement anything from custom storage to a <abbr title="Content Delivery Network">CDN</abbr> to upload progress meters. So learning how to use the new API is well worth the effort.</p>

<p><em>Please post any corrections in the comments below. Thanks.</em></p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2009/django-file-upload-handling-examples/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Facebook App using Django</title>
		<link>http://abing.gotdns.com/posts/2008/writing-a-facebook-app-using-django/</link>
		<comments>http://abing.gotdns.com/posts/2008/writing-a-facebook-app-using-django/#comments</comments>
		<pubDate>Wed, 31 Dec 2008 05:31:59 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=235</guid>
		<description><![CDATA[I recently found myself writing my first Facebook app using Python with the Django web framework. I have to admit that it was not a very pleasant experience. The usual Django development cycle of programming and testing locally does not work. I have a very simple workflow nailed down when writing Django apps: write, test [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I recently found myself writing my first Facebook app using Python with the Django web framework. I have to admit that it was not a very pleasant experience. The usual Django development cycle of programming and testing locally does not work. I have a very simple workflow nailed down when writing Django apps: write, test locally, commit to VCS, and upload to server. When writing a Facebook app, I had to change the current workflow a bit: write, commit to VCS, upload to server, test <strong>on production</strong>.</p>

<p>Facebook, being a PHP-powered site, likes to make the assumption that you will also be writing your app using PHP. They don&#8217;t even make any efforts to hide their bias towards PHP. The &#8220;official&#8221; client library is for PHP. The example program they give to you the first time you sign up is written in PHP. All the relevant starting points all lead towards PHP-centric development.</p>

<p>Thankfully, there are those who realize that PHP is not the be-all and end-all to programming web applications. You can find <a href="http://wiki.developers.facebook.com/index.php/Client_Libraries">unofficial client libraries</a> for other programming languages. Download and install the client library for your programming language of choice and follow the documentation and hopefully you get to have everything working on your first try.</p>

<p><span id="more-235"></span></p>

<p>If you are programming a web-based Facebook app in Python, you will have two choices:</p>

<ol>
<li><p><a href="http://code.google.com/p/pyfacebook/">PyFacebook</a> &#8211; a little bit on the heavy side since it comes with a framework-neutral core plus Django integration and Google App Engine support. It seems to be more actively maintained. The latest revision was on December 2, 2008 at the time of writing.</p></li>
<li><p><a href="http://code.google.com/p/minifb/">minifb</a> &#8211; small. However it seems that activity has stopped since February 2008.</p></li>
</ol>

<p>The choice of client library was a no-brainer for me since the site I am working on was written using Django. After downloading and installing PyFacebook I was able to get a minimal Facebook app up and running. By &#8220;up and running&#8221; I mean I can view the app&#8217;s canvas page on Facebook. However updates to my profile via profile.setFBML() do not seem to be working. After a bit of digging, I was able to find the culprit in a <a href="http://code.google.com/p/pyfacebook/issues/detail?id=82">bug report</a>. The modifications suggested by the issue reporter fixed the problem.</p>

<p>The app I was making was supposed to post updates to a Facebook Page. Facebook Pages are a relatively new feature and as a result <a href="http://wiki.developers.facebook.com/index.php/Facebook_Pages">documentation for it is a bit lacking</a>. The IRC transcript in the Wiki page for Facebook Pages provided some useful clues. There are two things you need to ensure if you need to write a Django view that has to update a Facebook Page:</p>

<ol>
<li><p><strong>Do not</strong> use <code>@facebook.require_login()</code> decorator.</p></li>
<li><p>The <code>uid</code> parameter for the <code>profile.setFBML()</code> call must be taken from the <code>fb_page_id</code> query parameter.</p></li>
</ol>

<p>For example:</p>

<pre>from django.template import loader, RequestContext

def update_page_profile(request):
    # facebook attribute in request is added by FacebookMiddleware
    uid = request.GET.get('fb_page_id')
    if uid:
        ctx = RequestContext(request, {'page_id': uid})
        # Do whatever you need to do here...
        t = loader.get_template('facebook/page_fbml.xml')
        # Render the template into the profile parameter for setFBML.
        # We do not use the deprecated markup parameter.
        request.facebook.profile.setFBML(profile=t.render(ctx), uid=uid)
        # Return a redirect to the profile URL for the page.
        # Note that we do not use Django HttpResponseRedirect here.
        return request.facebook.redirect(request.facebook.get_url('profile', id=uid))
    else:
        # Do something else here if the view did not get called
        # with the fb_page_id parameter. One possibility is to check if we got
        # called with a valid user ID and do something completely different.
        pass
</pre>

<p>One other thing to note about &#8220;profile boxes&#8221; in Facebook Pages is that they do not automatically update every time you view the Facebook Page. That is, you will need to provide a way of calling the update view manually. What I did was set the update view URL as the &#8220;Page Edit URL&#8221; for the app when embedded in a Facebook Page. Ideally you should set &#8220;Page Edit URL&#8221; to output a canvas page where the page admin can update settings for the app. Because the Facebook app I was making was mainly intended for internal use, I opted out of having a dedicated &#8220;Page Edit&#8221; canvas page and instead linked it directly to the profile update view URL.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/writing-a-facebook-app-using-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ditching PHP: Alternatives to PHP</title>
		<link>http://abing.gotdns.com/posts/2008/ditching-php-alternatives-to-php/</link>
		<comments>http://abing.gotdns.com/posts/2008/ditching-php-alternatives-to-php/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 08:46:03 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=222</guid>
		<description><![CDATA[You have worked around the quirks and you have lived with the inconsistencies. You have stood by and watched your code fail spectacularly between minor point releases. You scrambled to fix your code&#8217;s dependence on register_globals set to on when they got turned off by default in version 4.2.0. You have lived with the disappointment [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>You have worked around the quirks and you have lived with the inconsistencies. You have stood by and watched your code fail spectacularly between minor point releases. You scrambled to fix your code&#8217;s dependence on <code>register_globals set</code> to on when they got turned off by default in version 4.2.0. You have lived with the disappointment when version 5 failed to deliver on better object orientation. There have been a lot of warning signs telling you to look for better alternatives, but still you persevered. Then came the recent changes that really make you shake your head in disbelief. Face it, PHP&#8217;s direction as of late has really taken a downturn. You&#8217;re thinking it&#8217;s time to look for alternatives.</p>

<p>If you are one of those folks who have been using PHP <strong>and nothing but PHP</strong> for a long time you will be hard pressed to find an alternative. PHP is, after all, one of those things that are &#8220;easy to get into, but difficult to get out of&#8221;. PHP lures you in with its forgiving nature, vast library of pre-built extensions, ease of deployment and just plain &#8220;instant gratification&#8221;. It&#8217;s easy to forget that there are other languages for server-side programming/scripting.</p>

<p><span id="more-222"></span></p>

<h2>More Tools for your Toolbox</h2>

<p>When I was teaching CS classes back then, I always told my students <strong>never rely on a single programming language and never tie yourself to a single platform</strong>. I have always stressed the importance of learning more than one programming language and making sure that whatever you do, do it cross-platform if possible. By not limiting yourself to one language or platform, you will be able to develop solutions using the right tools for the problem at hand.</p>

<p>The following is a short list of programming languages that I have used in the past. These are my &#8220;bread and butter&#8221; languages in addition to PHP. These are also the reasons why I found it easy to ditch PHP. If you have never used any other programming language besides PHP, perhaps you should take a look at what else is out there.</p>

<h2>One Interface Behind Them All</h2>

<p>In theory, you can use <strong>any</strong> programming language to do server-side programming. You read that right: you can use any programming (or scripting) language. You can use C, C++, Fortran, Haskell, Java, Lisp, Lua, Perl, PHP, Python, Ruby, and so on. You can use whatever you want, as long you are able to receive input and send output via the Common Gateway Interface or CGI.</p>

<p>Server-side programming/scripting essentially involves two basic operations:</p>

<ol>
<li>Receiving and acting on a <strong>request</strong>;</li>
<li>Sending back a <strong>response</strong>.</li>
</ol>

<p>CGI acts as a bridge between your web server and your server-side program/script. When your web server receives a request and it sees that request as a request to execute a program/script on the server, it will set up everything that is necessary to run your program/script. It then runs the program/script, captures its output, if any, and sends it back to the client who issued the request. In Unix terms, any program/script that can take input from stdin and send output to stdout can be used on a web server that supports CGI. This is an overly simplified description. If you wish to learn more about CGI, use <a href="http://www.google.com/search?hl=en&#038;q=common+gateway+interface">&#8220;the Google&#8221;</a>.</p>

<p>Because the server runs the CGI program/script as an external process to handle each request, this means that there is an overhead for each request. To boost performance, modern web servers have come up with ways of eliminating or reducing the overhead from external process creation. For instance, Apache allows you to create modules that act as filters and handlers for requests. In most cases, PHP will have been installed as an Apache handler on your server which embeds the PHP interpreter in the running Apache process, eliminating the need to create an external process to run your PHP script. There is also an extension to the CGI standard called <a href="http://www.fastcgi.com/">FastCGI</a> which takes a different approach. FastCGI runs several instances of your program/script as long-running background processes. The webserver then connects to these processes whenever a requests requires the use of CGI, sends the request and collects the response and sends it back to the client.</p>

<p>Of course, these days you care less about the details and worry more about what your program/script does.</p>

<h2>Is it &#8220;Programming&#8221; or is it &#8220;Scripting?&#8221;</h2>

<p>At the heart of it, programming is programming and scripting is programming using a scripting language. In the early days, it&#8217;s easy to differentiate between &#8220;scripting&#8221; and &#8220;programming&#8221;. Scripts were written using &#8220;interpreted&#8221; programming languages which typically ran inside another program (e.g., CAD with Lisp scripting) or a stand-alone interpreter. &#8220;Programs&#8221;, in the original sense of the word, were written using &#8220;compiled&#8221; programming languages.</p>

<p>These days, the distinction has been blurred with the advent of <strong>compiled</strong> programming languages that are run using an interpreter. Java is just one example of this. You write your Java program and then compile it into machine-independent <strong>byte-code</strong> which you then run using a Java virtual machine or JVM. A JVM is essentially an interpreter but these days, we also have the so-called JVM with Just-in-Time compilation which maps machine-independent byte-code into native instructions for the CPU running the VM.</p>

<p>It&#8217;s all become so confusing these days with all the recent developments in VM technology. The distinction between &#8220;scripting&#8221; and &#8220;programming&#8221; has eroded. Personally I just prefer to call it <strong>programming</strong>. So from this point onwards, I will simply use the term &#8220;programming&#8221; to refer to &#8220;scripting&#8221; as well and &#8220;programs&#8221; to refer to &#8220;scripts&#8221;.</p>

<p>One more thing: Knowing how to write HTML and CSS does not make you a programmer, so please stop calling yourself a programmer or &#8220;coder&#8221; if all you know is HTML and CSS.</p>

<h2>The Duct Tape of the Internet</h2>

<p>Let&#8217;s begin with the grand daddy of server-side programming: <a href="http://www.perl.org/">Perl</a>. Created by Larry Wall in 1987, it has evolved into a true, general-purpose programming language. It was developed primarily to automate system administration on Unix systems. It began to gain popularity in the early 1990&#8217;s as a convenient way to write CGI scripts. PHP can trace it&#8217;s origins back to a CGI script written by Rasmus Lerdorf using Perl. That&#8217;s right, a scripting language begat <em>another</em> scripting language. You can see shades of Perl in PHP, the most visible is the use of the $ symbol to start a variable name.</p>

<p>Perl may come across as a quirky, cryptic language to some. It has also been the butt of jokes in recent times with the advent of newer (and sexier) programming languages. The Perl mantra TIMTOWTDI (there is more than one way to do it) is both a blessing and a curse. Take printing a progress bar for example. As one person found out by asking the Perl monks, <a href="http://www.perlmonks.org/?node_id=396839">TMTOWTDI</a>. But make no mistake. Perl is a very powerful language, with a friendly community and a <a href="http://cpan.org/">huge library of pre-written modules</a>.</p>

<p>The standard Perl installation comes with the CGI module which allows you to get up and running with CGI very quickly. You can use Perl to write a simple CGI script without using the CGI module. However, using the CGI module frees you from having to deal with a raw CGI environment. It also gives you with useful functions for handling query strings and forms, URL escaping, and error handling.</p>

<p>It also comes with a standard for database interfaces and drivers (DBI and DBD). DBI will usually come pre-installed along with commonly used database drivers. If you are familiar with ODBC or if you have played around with PDO, the Perl DBI is similar in spirit. It provides you with a consistent interface for database access and more importantly, it gives you <strong>prepared statements</strong> even if the underlying database does not support it.</p>

<p>More importantly, most virtual hosting shops support already support Perl in addition to PHP. You will probably have two options, depending on your hosting provider. First option would be to write your programs as just plain CGI programs and upload them to a special directory on your account. Second option would be to write your program to take advantage of <a href="http://perl.apache.org/">mod_perl</a> if it is installed by your hosting provider. mod_perl not only allows you to write CGI programs, it also allows you to create Apache modules using Perl.</p>

<h2>Over-Engineered Beyond Help</h2>

<p>Next up we have the programming language that no self-respecting software &#8220;engineer&#8221; can do without: Java. Although it has all the required facilities needed to write CGI programs, if you must do something in Java, you should do it properly. And the proper way of server-side programming in Java is to write a Java Servlet. In order to do that, you need to run it inside a Servlet Container such as <a href="http://tomcat.apache.org/">Apache Tomcat</a>.</p>

<p>Java already has database connectivity covered with its standard JDBC. Odds are that your servlet container can also run JSP&#8217;s which allow you to embed Java code in your markup. Your servlet container then takes these JSP&#8217;s, compiles them into a servlet when handling the first request and uses the compiled servlet to handle subsequent requests.</p>

<p>As you have probably learned by now (or not), it is better to separate your program into distinct areas using the Model-View-Controller paradigm. Java supports this out of the box. You have POJO&#8217;s (plain old Java objects) to use for your model. The servlet serves as controller. JSP provides you with the view. Once you have the basics nailed down, it&#8217;s all very simple onwards. Or not&#8230;</p>

<p>As your program grows in size and complexity you will find the simple MVC approach using POJOs, servlets and JSP&#8217;s become unwieldy at best. You will be looking for a better solution. Java has a standard for developing large scale web applications too. J2EE is a collection of standards that encompass everything you need to develop large scale web applications and service oriented applications (SOA&#8217;s). Newbies will probably be overwhelmed by the amount of complexity involved in developing and deploying large-scale apps using J2EE. It has more acronyms than a bowl of alphabet soup. Once you&#8217;ve finished wading through your acronym soup, prepare to swim in XML tag soup. Almost everything in a J2EE server is configured using XML. But then again, developing and deploying a large-scale J2EE app was never meant to be a job for a lone developer and there are tools you can use to tame all that XML.</p>

<p>As for hosting your Java apps, typically you need to find a specialized hosting service of which there is no short supply.</p>

<h2>Ooooooh! Shiny!</h2>

<p>Then there&#8217;s <a href="http://www.ruby-lang.org/en/">Ruby</a>. First released to the public in 1995 by Yukihiro Matsumoto, it was an obscure programming language from Japan that exploded in popularity in recent years (due to a well-marketed web programming framework). As one fellow so succinctly put: &#8220;Ruby is the language for trendy, non-conformists.&#8221;</p>

<p>Ruby by itself is a very capable language with a large set of libraries included as standard. The CGI library is one of them so you can also get to writing server-side programs in no time. Like Perl and Java, it also comes with a standard library for interfacing with databases.</p>

<p>I tried Ruby some time early last year but I find its reliance on on <code>begin</code> and <code>end</code> to be a major annoyance at best. That&#8217;s the reason why I hated programming in Pascal and VB so much. Come on, if braces worked for C, C++, Java, Javascript, Perl, PHP, etc. why bother using whole words to delineate blocks of code? Another sticking point, at least at the time, was performance. For small one-off scripts, it&#8217;s pretty decent. However, for larger more complex programs which are spread across several files, performance really sucks! The time it takes to launch the interpreter, byte compile your code and run it was simply unacceptable for me. If you&#8217;re going to use Ruby for CGI programming, use FastCGI or some other way of keeping a cached copy of your byte-compiled code in memory.</p>

<p>With those two aside, I find some features that make Ruby hard to resist. There&#8217;s &#8220;monkey patching&#8221;. Ruby classes are open classes. This means two things: you can spread class definitions across multiple files and you can modify built-in or standard library class behavior. Being able to spread class definitions across files helps to make your code more manageable as it grows in complexity and size. By modifying behavior of built-in or standard library classes you&#8217;re able to create semantics that are more suited to the job at hand. This can also be a problem, especially if your program is reliant on third-party libraries, as it is possible that the modified behavior is not what you really want. But when done carefully, it can extend the usefulness of existing classes (like to what <a href="http://mootools.net/">Mootools</a> does for Javascript).</p>

<p>Ruby also makes it relatively simple to map data from a text file or database record into a dynamically generated class at run-time. This proves useful in creating ORM&#8217;s (object-relational mappings). Most Java ORM&#8217;s use a clunky approach glued together with unholy amounts of XML. Ruby makes it easy by providing the facilities necessary as built-ins.</p>

<p>Another great feature is class composition. This is similar to the concept of interfaces and mixins in other languages. You define a set of methods and properties in a <code>module</code>. When you need them in your class, you simply <code>include</code> the module.</p>

<p>As for finding hosting providers that support Ruby, thanks to a popular web programming framework, most hosting providers now support Ruby in addition to PHP and Perl. Just like Java however, you can get better bang for your buck by going with a specialized Ruby hosting package.</p>

<h2>Batteries Included</h2>

<p>Now we come to my programming language of choice: <a href="http://www.python.org/">Python</a>. While using whitespace to delimit blocks of code may seem strange to those who come from the &#8220;bracketed&#8221; programming languages such as C, Java, Perl or PHP, it actually makes your programs easy to read <strong>by default</strong>. You don&#8217;t need to remember any silly coding and indenting conventions. As long as you use a consistent means of indenting your code (4 spaces is recommended), you are pretty much set when it comes to readability. It was a bit uncomfortable at first but blocks delineated by indentation sort of grows on you eventually.</p>

<p>With that <strong>single</strong> &#8220;unusual&#8221; quirk aside, Python has all of the tools you need to get started with server-side programming: &#8220;Batteries Included&#8221;. Simply <code>import</code> the cgi module in your code and start plugging away at your program. However just like in Java, there is a standard way of doing things and the standard way of server-side programming using Python is through the use of <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a>. Python&#8217;s WSGI is similar in spirit to Java&#8217;s Servlet specification. It defines a standard way of writing programs that have to interface with a web server using a request-response model. It takes the server&#8217;s execution environment, the client&#8217;s request, and the server&#8217;s response and packages it into one coherent specification.</p>

<p>One more thing that I like about programming in Python is that your program sort of describes itself. You spend less time writing descriptive comments as to what a section of your code does, unlike other programming languages. Chances are that you can write a Python program now without any documenting comments, come back six months later and look at your code and you will still be able to read and understand what it does.</p>

<p>Performance-wise, Python has consistently outperformed PHP and Ruby as of late. Python programs are compiled into byte-code before it gets executed by the Python VM (interpreter) just like Java. However, unlike Java, there is no explicit compilation step necessary. Unlike Java, Python can run your code regardless of whether or not it is in the byte-code compiled form. Your byte-compiled Python code essentially acts as an on-disk cache for the VM. When you first run your program, the Python interpreter will byte-compile your code and if it can, it will write the byte-compiled code into a file with a .pyc extension. The next time you run your program, the interpreter will check if there is a .pyc file present. If found, it will check to see if your source file is newer than the .pyc file. If your .pyc file is up to date, the interpreter skips the byte-compilation step and runs the .pyc file instead. If your source file is newer, it will byte-compile it and try to write it to disk. This is another reason why I prefer Python over anything else. I can distribute just the .pyc files without the .py source files. I am all for &#8220;open source&#8221; but there times when you just don&#8217;t want clients to be dicking around with your code.</p>

<p>As for libraries, chances are good that the standard Python installation already has everything you need. Python also comes with a standard for database interfaces called DBI, which like its Perl counterpart, provides you with a consistent interface regardless of what database you are using. It also provides you with prepared statements which can be emulated in the driver in case your database does not support it.</p>

<p>Just like Ruby and Java, you are better off going with a specialized Python hosting package if you are going to do WSGI. If you only need to write CGI programs in Python, then many hosting providers already support Python in addition to Perl, PHP, and Ruby.</p>

<p>So there you have it. I hope this goes to show that PHP is not the be all and end all to programming.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/ditching-php-alternatives-to-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OMG!!! Ponies!!!</title>
		<link>http://abing.gotdns.com/posts/2008/omg-ponies/</link>
		<comments>http://abing.gotdns.com/posts/2008/omg-ponies/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 03:54:33 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=218</guid>
		<description><![CDATA[Now see this is why I love Django. It&#8217;s an awesome framework with a great community behind it.

a
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>Now see <a href="http://avalonstar.com/blog/2008/sep/9/web-framework-ponies/">this is why I love Django</a>. It&#8217;s an awesome framework with a great community behind it.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/omg-ponies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Definitely Time To Ditch PHP</title>
		<link>http://abing.gotdns.com/posts/2008/definitely-time-to-ditch-php/</link>
		<comments>http://abing.gotdns.com/posts/2008/definitely-time-to-ditch-php/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 03:29:54 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[You are doing it WRONG!!!]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=211</guid>
		<description><![CDATA[Good bye PHP. You have been a good bread and butter language for me. Sorry to say the dumbosity of the design decisions being made about you are too much to live with. It&#8217;s time I moved on to bigger and better things with a better sense of direction.

Reading the IRC chat log that lead [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>Good bye PHP. You have been a good bread and butter language for me. Sorry to say the <a href="http://wiki.php.net/_media/rfc/php.ns.txt?id=rfc%3Anamespaceseparator&#038;cache=cache">dumbosity</a> of the design decisions being made about you are too much to live with. It&#8217;s time I moved on to <a href="http://python.org/">bigger</a> and <a href="http://djangoproject.com/">better</a> things with a <a href="http://www.python.org/dev/peps/">better sense of direction</a>.</p>

<p><span id="more-211"></span></p>

<p>Reading <a href="http://wiki.php.net/_media/rfc/php.ns.txt?id=rfc%3Anamespaceseparator&amp;cache=cache">the IRC chat log that lead to the &#8220;backslash as namespace separator&#8221; decision</a> just affirms my impression that the PHP language is in the hands of neurotic, crack-smoking monkeys. Well except for a few people like Dmitry. Apparently there are two problems with &#8220;::&#8221; that prove too difficult for them to solve:</p>

<ol>
<li><p>There are some modifications needed for &#8220;::&#8221; to work properly but these modifications will break existing code. I would say, what the hell! Break existing code! PHP6 will break existing code anyway. But no, they also want namespaces in PHP5 so there!</p></li>
<li><p>The engine can&#8217;t detect ambiguity without calling autoload. It introduces the so-called &#8220;autoload bomb&#8221;. Apparently, calling autoload once for each namespace as Dmitry suggested is &#8220;impracticable[sic] because it relies on the programmer to know when ambiguity arises&#8221;. Huh?!? Forgive me but isn&#8217;t it the job of the compiler/interpreter to detect such an ambiguity and <strong>tell the programmer</strong>???</p></li>
</ol>

<p>So instead of fixing the fundamental problems with the engine, they want to use the band-aid solution of adding a different syntax for namespaces. Oh wait, maybe it&#8217;s because the engine is so horribly designed that it&#8217;s impossible to write in sensible changes without having the whole thing fall apart completely?</p>

<p>I have been fighting so hard to keep <a href="http://tnx.nl/php.html">this</a> from swaying me away from PHP. I have lived through and worked around the inconsistencies and quirks of the language, but this &#8220;backslash as namespace separator&#8221; crap is the last straw. It sucks that I have to maintain a lot of PHP code but from this point onwards, I will no longer use PHP for new projects.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/definitely-time-to-ditch-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Is It Time to Ditch PHP?</title>
		<link>http://abing.gotdns.com/posts/2008/is-it-time-to-ditch-php/</link>
		<comments>http://abing.gotdns.com/posts/2008/is-it-time-to-ditch-php/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 08:18:06 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[You are doing it WRONG!!!]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=204</guid>
		<description><![CDATA[PHP has long been a bread and butter language for me when it came to web-based projects. It&#8217;s what got me started in the whole web development business and essentially kick-started my whole career as a systems developer. But alas, recent developments in PHP land come as an unwelcome surprise. I&#8217;m talking about the much [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>PHP has long been a bread and butter language for me when it came to web-based projects. It&#8217;s what got me started in the whole web development business and essentially kick-started my whole career as a systems developer. But alas, recent developments in PHP land come as an unwelcome surprise. I&#8217;m talking about the much anticipated (for me anyway) namespace support. I have documented my basic gripes about PHP <a href="http://abing.gotdns.com/posts/2007/new-php5-based-framework-project-php5-and-lack-of-namespace-support-among-other-things/">elsewhere</a>. So I won&#8217;t go rambling about them again. I was excited to hear about namespaces <strong>finally</strong> getting implemented in PHP6 and backported to PHP5. But then when you read about <a href="http://wiki.php.net/rfc/namespaceseparator">bullshit like this</a> you can&#8217;t help but wonder if the language&#8217;s direction has been taken over by a pack of neurotic, crack-smoking monkeys. Namespaces are a very important feature if one were to write large amounts of code without having to worry about symbol name clashes.</p>

<p><span id="more-204"></span></p>

<p>So, they want to replace the de facto standard namespace separator &#8220;::&#8221; with &#8220;\&#8221;. That&#8217;s right: replace double-colon with a backslash! Why? It&#8217;s because &#8220;::&#8221; is already being used in class method invocations and it will cause problems during parsing. Consider the following:</p>

<pre>class Lol {
    public static function whut() {
    }

namespace Lol;

function whut() {
}
</pre>

<p>Elsewhere:</p>

<pre>Lol::whut();
</pre>

<p>When you write <code>Lol::whut()</code>, which one are you talking about? Is it the <code>static</code> function in the class <code>Lol</code>? Or is it the function in the <code>Lol</code> namespace? I can think of a few solutions to this very simple problem besides changing the damned separator character.</p>

<ol>
<li><p>Throw an exception during parsing/compilation and complain that the symbol Lol has already been defined. Ideally it should say something sensible like: &#8220;Class name &#8216;Lol&#8217; defined in main namespace conflicts with existing namespace definition &#8216;Lol&#8217; found in <strong>FILE</strong>, line <strong>LINE</strong>.&#8221; For dynamically generated code, throw a runtime error and halt program execution. This is how C++ handles it, I can&#8217;t see why PHP can&#8217;t do the same. I would prefer it this way because I don&#8217;t want some moron programmer who is using my Lol library to write a class named Lol in the main namespace!</p></li>
<li><p>Throw an exception like in #1 but make it a non-fatal exception and just let the class method defined in the main namespace take precedence. Or even let the function in the namespace take precendence. Do it one way over the other <em>but tell the programmer that there is a problem</em> with <strong>his code</strong>!</p></li>
<li><p>Force <code>Lol::whut()</code> to resolve to the class method and <code>::Lol::whut()</code> to resolve to the function defined in namespace <code>Lol</code>. Or vice versa.</p></li>
</ol>

<p>I would really love to see arguments leveled against the 3 solutions above because changing the separator character is just plain stupid. Oh, and it&#8217;s butt ugly too. <strike>Sure it&#8217;s just in RFC but if this sort of stupid shit makes it into PHP6 then it&#8217;s time to say bye-bye PHP&#8230;</strike> It looks like they have their hearts set on using backslash as the namespace separator and <a href="http://news.php.net/php.internals/41374">it&#8217;s pretty much set in stone</a>.</p>

<p>On a side note, when I was reading the RFC I had to take a second look at the date to make sure that it does not say April 1, 2008. They were considering the &#8220;smiley&#8221; as a namespace separator?!? Surely you jest!</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/is-it-time-to-ditch-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse 3.4 (Ganymede) First Impressions</title>
		<link>http://abing.gotdns.com/posts/2008/eclipse-34-ganymede-first-impressions/</link>
		<comments>http://abing.gotdns.com/posts/2008/eclipse-34-ganymede-first-impressions/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 05:36:18 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=186</guid>
		<description><![CDATA[Ever since my last Eclipse 3.3 install broke down due to a botched update, I have given up using it and started using Vim. I still keep an eye out for new developments for the platform though. The recent release version 3.4 codenamed Ganymede had a lot of promise.

I tried the latest version of Eclipse [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>Ever since my last Eclipse 3.3 install broke down due to a botched update, I have given up using it and started using Vim. I still keep an eye out for new developments for the platform though. The recent release version 3.4 codenamed Ganymede had a lot of promise.</p>

<p>I tried <a href="http://eclipse.org/ganymede/">the latest version of Eclipse</a> the other night. As usual, I downloaded the &#8220;Eclipse Classic&#8221; tarball for Linux. It&#8217;s an iffy release to say the least, akin to KDE 4.0. There have been major changes in the platform itself. But the most visible part is the way plugins are <a href="http://wiki.eclipse.org/Equinox_p2_User_Interface">managed</a> and <a href="http://wiki.eclipse.org/Equinox_p2_Getting_Started">installed</a>. Personally I had high hopes for the new UI as the old one was a bit unwieldy to work with. Unfortunately, the new UI still needs a lot more work done. The main problem I had with the new UI is that even the plugins that already came with the package I downloaded <strong>still</strong> show up int the Available Software window. There also appears to be a bug where if you check and then uncheck a plugin, it will still install that plugin. There are also some new issues and regressions introduced by the new UI that they still have to work on.</p>

<p>Right now, I&#8217;m back to using Vim. Eclipse 3.4 is just too flaky for me at the moment.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/eclipse-34-ganymede-first-impressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When is a Closure not a Closure?</title>
		<link>http://abing.gotdns.com/posts/2008/when-is-a-closure-not-a-closure/</link>
		<comments>http://abing.gotdns.com/posts/2008/when-is-a-closure-not-a-closure/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 04:08:22 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[You are doing it WRONG!!!]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=173</guid>
		<description><![CDATA[Answer: When it&#8217;s a PHP closure. It appears that PHP will have closures in 5.3. But as per usual, it does not work in ways that you would expect it to work. See the comment by &#8220;sapphirecat&#8221; on this
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>Answer: When it&#8217;s a <a href="http://wiki.php.net/rfc/closures">PHP closure</a>. It appears that PHP will have closures in 5.3. But as per usual, it does not work in ways that you would expect it to work. See the comment by &#8220;sapphirecat&#8221; on this <a href="http://www.toosweettobesour.com/2008/07/21/php-53-and-closures/trackback/"article</a>. There still appears to be a problem when you &#8220;rope&#8221; off a global:</p>

<blockquote>
  <p>So they seem to have taken the usual half-broken approach: you can have read-only closures which are immune to changes to a global variable, or you can have read-write closures which remember changes, but those changes leak back into the global variable.</p>
</blockquote>

<p>Oops! Closures are not supposed to do that! It sort of defeats the purpose of having closures in the first place. There is a workaround to the problem but that is one more quirk that you have to remember when working with PHP. Two steps forward, one step back.</p>

<p>a</p>

<p></a></p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/when-is-a-closure-not-a-closure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated encfs Source Packages for Arch Linux</title>
		<link>http://abing.gotdns.com/posts/2008/updated-encfs-source-packages-for-arch-linux/</link>
		<comments>http://abing.gotdns.com/posts/2008/updated-encfs-source-packages-for-arch-linux/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 16:35:29 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Arch Linux]]></category>
		<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[AUR]]></category>
		<category><![CDATA[encfs]]></category>
		<category><![CDATA[packages]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/?p=165</guid>
		<description><![CDATA[So I wanted to decrypt an encfs encrypted directory on my laptop recently. I was greeted with the following error:

encfs: error while loading shared libraries: librlog.so.1: cannot open shared object file: No such file or directory

It turns out that there has been a recent update to rlog and the encfs package was somehow left out [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>So I wanted to decrypt an <a href="http://www.arg0.net/encfs">encfs</a> encrypted directory on my laptop recently. I was greeted with the following error:</p>

<p><code>encfs: error while loading shared libraries: librlog.so.1: cannot open shared object file: No such file or directory</code></p>

<p>It turns out that there has been a recent update to <code>rlog</code> and the encfs package was somehow left out of the rebuild. It also appears that the <code>encfs</code> package has disappeared from the Arch Linux Community Repository.</p>

<p>I have been rolling my own Arch Linux packages for quite a while now. I have been using a few locally built packages on my system. Since I already have two custom packages that I wrote myself, I figured it would be a good idea to share them. I&#8217;m too lazy to register with AUR and upload these packages and it would be likely that I would forget about updating them as well. So I am posting them here for consumption by the general public.</p>

<p>Download the <a href="encfs: error while loading shared libraries: librlog.so.1: cannot open shared object file: No such file or directory">Arch Linux source package for encfs</a> here. To build this:</p>

<ol>
<li>Make a directory to hold the files contained in the encfs source package.</li>
<li>Unpack the tarballed source package into the directory you created.</li>
<li>Install <code>boost</code>. Boost is a C++ library that is used by recent versions of encfs. You will also need to install <code>fuse</code> in case you don&#8217;t have it yet.</li>
<li>Change into the encfs source package directory you made and run <code>makepkg -c</code>. This will download the source for the current version of encfs. When <code>makepkg</code> finishes you will end up with an installable package in your current directory.</li>
<li>Install the package using <code>pacman encfs-1.4.2-1-i686.pkg.tar.gz</code> (replace encfs-1.4.2-1-i686.pkg.tar.gz with the correct filename for your custom-built package.)</li>
</ol>

<p>There you go. You should have <code>encfs</code> working now.</p>

<p>You can also find <a href="http://pyme.sourceforge.net/">pyme</a> in my <a href="/AUR/">AUR directory</a>.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2008/updated-encfs-source-packages-for-arch-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
