<?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>Perplexed Labs &#187; c++</title>
	<atom:link href="http://blog.perplexedlabs.com/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.perplexedlabs.com</link>
	<description>web development war stories from the frontlines to the backend</description>
	<lastBuildDate>Thu, 09 Sep 2010 17:11:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Python libwkhtmltox module &#8211; wrapping a C library using Cython</title>
		<link>http://blog.perplexedlabs.com/2010/09/09/python-libwkhtmltox-module-wrapping-a-c-library-using-cython/</link>
		<comments>http://blog.perplexedlabs.com/2010/09/09/python-libwkhtmltox-module-wrapping-a-c-library-using-cython/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 12:00:50 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[cython]]></category>
		<category><![CDATA[libwkhtmltox]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[wkhtmltoimage]]></category>
		<category><![CDATA[wkhtmltopdf]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://blog.perplexedlabs.com/?p=483</guid>
		<description><![CDATA[First of all, big shout out to antialize for creating wkhtmltopdf (github repo). Also, this project is being hosted on GitHub @ http://github.com/mreiferson/py-wkhtmltox. wkhtmltox What is wkhtmltox you ask? It's a utility built on Nokia's Qt framework for converting HTML (including images, CSS, and Javascript) to a PDF or image. When Qt introduced it's webkit [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2010/03/04/python-data-sharing-in-the-multiprocessing-module/' rel='bookmark' title='Permanent Link: Python data sharing in the multiprocessing module'>Python data sharing in the multiprocessing module</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/04/22/django-url-parameter-passing-and-python-strings/' rel='bookmark' title='Permanent Link: Django URL Parameter Passing and Python Strings'>Django URL Parameter Passing and Python Strings</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/03/02/django-up-in-your-cron/' rel='bookmark' title='Permanent Link: Django Up In Your CRON'>Django Up In Your CRON</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>First of all, big shout out to antialize for creating <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a> (<a href="http://github.com/antialize/wkhtmltopdf">github repo</a>).</p>
<p>Also, this project is being hosted on GitHub @ <a href="http://github.com/mreiferson/py-wkhtmltox">http://github.com/mreiferson/py-wkhtmltox</a>.</p>
<h2><a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltox</a></h2>
<p>What is wkhtmltox you ask?  It's a utility built on <a href="http://qt.nokia.com/">Nokia's Qt</a> framework for converting HTML (including images, CSS, <strong>and Javascript</strong>) to a PDF or image.  When Qt introduced it's <a href="http://doc.trolltech.com/4.6/qtwebkit.html">webkit module</a> it made it relatively easy to leverage it's rendering engine to produce high quality output.</p>
<p>wkhtmltox 0.10.0beta5 introduced libwkhtmltox - a simple C API making it possible to embed this functionality in higher-level scripting languages.  I jumped at the opportunity to build Python bindings...</p>
<p>First I tried <a href="http://www.riverbankcomputing.co.uk/software/sip/intro">SIP</a>, which is actually used for the Qt bindings.  A variety of issues coupled with poor documentation led me to search for other solutions.  I won't bore you with the details because it seems there are better ways...</p>
<h2><a href="http://www.cython.org/">Cython</a></h2>
<p>Note: I'm not talking about CPython (the default Python implementation written in C).  I'm talking about a toolset to build C extensions for Python.  The two major use cases being speed or, in my case, wrapping a C library.</p>
<p>It's really easy to get up and running, Cython the language is a hybrid of C and Python.  You write scripts with a .pyx extension, make things modular with .pxd files, and handle all the building and installation with <a href="http://docs.python.org/distutils/">distutils</a>.</p>
<p>Let's take a look at the API libwkhtmltox exposes (I'm only showing lines relevant to this post):</p>
<pre class="brush: cpp;">
struct wkhtmltopdf_global_settings;
typedef struct wkhtmltopdf_global_settings wkhtmltopdf_global_settings;

struct wkhtmltopdf_object_settings;
typedef struct wkhtmltopdf_object_settings wkhtmltopdf_object_settings;

struct wkhtmltopdf_converter;
typedef struct wkhtmltopdf_converter wkhtmltopdf_converter;

CAPI int wkhtmltopdf_init(int use_graphics);
CAPI int wkhtmltopdf_deinit();

CAPI const char * wkhtmltopdf_version();

CAPI wkhtmltopdf_global_settings * wkhtmltopdf_create_global_settings();
CAPI wkhtmltopdf_object_settings * wkhtmltopdf_create_object_settings();

CAPI int wkhtmltopdf_set_global_setting(wkhtmltopdf_global_settings * settings, const char * name, const char * value);
CAPI int wkhtmltopdf_set_object_setting(wkhtmltopdf_object_settings * settings, const char * name, const char * value);

CAPI wkhtmltopdf_converter * wkhtmltopdf_create_converter(wkhtmltopdf_global_settings * settings);
CAPI void wkhtmltopdf_destroy_converter(wkhtmltopdf_converter * converter);

CAPI int wkhtmltopdf_convert(wkhtmltopdf_converter * converter);
CAPI void wkhtmltopdf_add_object(wkhtmltopdf_converter * converter, wkhtmltopdf_object_settings * setting, const char * data);

CAPI int wkhtmltopdf_http_error_code(wkhtmltopdf_converter * converter);
</pre>
<p>And let's also look at the basic example provided with the wkhtmltopdf source distribution (again, only relevant lines shown):</p>
<pre class="brush: cpp;">
wkhtmltopdf_init(false);
gs = wkhtmltopdf_create_global_settings();
wkhtmltopdf_set_global_setting(gs, &quot;out&quot;, &quot;test.pdf&quot;);
os = wkhtmltopdf_create_object_settings();
wkhtmltopdf_set_object_setting(os, &quot;page&quot;, &quot;http://doc.trolltech.com/4.6/qstring.html&quot;);
c = wkhtmltopdf_create_converter(gs);
wkhtmltopdf_add_object(c, os, NULL);
wkhtmltopdf_convert(c);
wkhtmltopdf_destroy_converter(c);
wkhtmltopdf_deinit();
</pre>
<p>I found it helpful to try to identify which methods needed to be exposed to user-space and which ones could be safely abstracted behind a cleanly wrapped Pythonic API.  I wrote the following test script to work towards:</p>
<pre class="brush: python;">
import wkhtmltox

pdf = wkhtmltox.Pdf()
pdf.set_global_setting('out', 'test.pdf')
pdf.set_object_setting('path', 'http://www.google.com')
pdf.convert()
</pre>
<p>The initialization of a Pdf instance handles all of the internal libwkhtmltox initialization.  See below for the .pyx script.  Of interest is how C structs and functions are exposed to the Cython script and then wrapped, with appropriate names, as Python methods of a class.  Astute observers will also notice that some of the function declarations differ slightly from the original libwkhtmltox header file.  In most cases Cython doesn't need the const, CAPI and other specific declarations.  Also, <strong>bint</strong> hints that even though the return value is an int we should convert this to a boolean on the Python side.</p>
<pre class="brush: python;">
cdef extern from &quot;wkhtmltox/pdf.h&quot;:
    struct wkhtmltopdf_converter:
        pass

    struct wkhtmltopdf_object_settings:
        pass

    struct wkhtmltopdf_global_settings:
        pass

    bint wkhtmltopdf_init(int use_graphics)
    bint wkhtmltopdf_deinit()
    char *wkhtmltopdf_version()

    wkhtmltopdf_global_settings *wkhtmltopdf_create_global_settings()
    wkhtmltopdf_object_settings *wkhtmltopdf_create_object_settings()

    bint wkhtmltopdf_set_global_setting(wkhtmltopdf_global_settings *settings, char *name, char *value)
    bint wkhtmltopdf_get_global_setting(wkhtmltopdf_global_settings *settings, char *name, char *value, int vs)
    bint wkhtmltopdf_set_object_setting(wkhtmltopdf_object_settings *settings, char *name, char *value)
    bint wkhtmltopdf_get_object_setting(wkhtmltopdf_object_settings *settings, char *name, char *value, int vs)

    wkhtmltopdf_converter *wkhtmltopdf_create_converter(wkhtmltopdf_global_settings *settings)
    void wkhtmltopdf_destroy_converter(wkhtmltopdf_converter *converter)

    bint wkhtmltopdf_convert(wkhtmltopdf_converter *converter)
    void wkhtmltopdf_add_object(wkhtmltopdf_converter *converter, wkhtmltopdf_object_settings *setting, char *data)

    int wkhtmltopdf_http_error_code(wkhtmltopdf_converter *converter)

cdef extern from &quot;wkhtmltox/image.h&quot;:
    struct wkhtmltoimage_global_settings:
        pass

    struct wkhtmltoimage_converter:
        pass

    bint wkhtmltoimage_init(int use_graphics)
    bint wkhtmltoimage_deinit()
    char *wkhtmltoimage_version()

    wkhtmltoimage_global_settings *wkhtmltoimage_create_global_settings()

    bint wkhtmltoimage_set_global_setting(wkhtmltoimage_global_settings *settings, char *name, char *value)
    bint wkhtmltoimage_get_global_setting(wkhtmltoimage_global_settings *settings, char *name, char *value, int vs)

    wkhtmltoimage_converter *wkhtmltoimage_create_converter(wkhtmltoimage_global_settings *settings, char *data)
    void wkhtmltoimage_destroy_converter(wkhtmltoimage_converter *converter)

    bint wkhtmltoimage_convert(wkhtmltoimage_converter *converter)

    int wkhtmltoimage_http_error_code(wkhtmltoimage_converter *converter)

cdef class Pdf:
    cdef wkhtmltopdf_global_settings *_c_global_settings
    cdef wkhtmltopdf_object_settings *_c_object_settings
    cdef bint last_http_error_code

    def __cinit__(self):
        wkhtmltopdf_init(0)
        self._c_global_settings = wkhtmltopdf_create_global_settings()
        self._c_object_settings = wkhtmltopdf_create_object_settings()

    def __dealloc__(self):
        wkhtmltopdf_deinit();

    def set_global_setting(self, char *name, char *value):
        return wkhtmltopdf_set_global_setting(self._c_global_settings, name, value)

    def set_object_setting(self, char *name, char *value):
        return wkhtmltopdf_set_object_setting(self._c_object_settings, name, value)

    def convert(self):
        cdef wkhtmltopdf_converter *c
        c = wkhtmltopdf_create_converter(self._c_global_settings)
        wkhtmltopdf_add_object(c, self._c_object_settings, NULL)
        ret = wkhtmltopdf_convert(c)
        self.last_http_error_code = wkhtmltopdf_http_error_code(c)
        wkhtmltopdf_destroy_converter(c)
        return ret

    def http_error_code(self):
        return self.last_http_error_code

cdef class Image:
    cdef wkhtmltoimage_global_settings *_c_global_settings
    cdef bint last_http_error_code

    def __cinit__(self):
        wkhtmltoimage_init(0)
        self._c_global_settings = wkhtmltoimage_create_global_settings()

    def __dealloc__(self):
        wkhtmltoimage_deinit();

    def set_global_setting(self, char *name, char *value):
        return wkhtmltoimage_set_global_setting(self._c_global_settings, name, value)

    def convert(self):
        cdef wkhtmltoimage_converter *c
        c = wkhtmltoimage_create_converter(self._c_global_settings, NULL)
        ret = wkhtmltoimage_convert(c)
        self.last_http_error_code = wkhtmltoimage_http_error_code(c)
        wkhtmltoimage_destroy_converter(c)
        return ret

    def http_error_code(self):
        return self.last_http_error_code
</pre>
<p>This is really my first attempt to get something working.  I'm sure there are bugs and perhaps better ways to go about this.  I always welcome questions/feedback.</p>
<p>I'm going to continue to support this project at <a href="http://github.com/mreiferson/py-wkhtmltox">http://github.com/mreiferson/py-wkhtmltox</a> - watch it!</p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2010/03/04/python-data-sharing-in-the-multiprocessing-module/' rel='bookmark' title='Permanent Link: Python data sharing in the multiprocessing module'>Python data sharing in the multiprocessing module</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/04/22/django-url-parameter-passing-and-python-strings/' rel='bookmark' title='Permanent Link: Django URL Parameter Passing and Python Strings'>Django URL Parameter Passing and Python Strings</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/03/02/django-up-in-your-cron/' rel='bookmark' title='Permanent Link: Django Up In Your CRON'>Django Up In Your CRON</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2010/09/09/python-libwkhtmltox-module-wrapping-a-c-library-using-cython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>13 Years On The Web &#8211; A Retrospective, Part II</title>
		<link>http://blog.perplexedlabs.com/2008/12/19/13-years-on-the-web-a-retrospective-part-ii/</link>
		<comments>http://blog.perplexedlabs.com/2008/12/19/13-years-on-the-web-a-retrospective-part-ii/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 16:45:34 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[aol]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[game programming]]></category>
		<category><![CDATA[perplexed]]></category>
		<category><![CDATA[vb]]></category>

		<guid isPermaLink="false">http://www.perplexedlabs.com/?p=96</guid>
		<description><![CDATA[In Part I, I detailed the formative phases of our web development careers.  A providential encounter with a magazine article, tons of free time, inherent curiosity, youthful ambition were the perfect storm that threw us into the world of programming. At this time, Matt was admittedly more of a programmer than I was.  While our [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2008/11/20/13-years-on-the-web-a-retrospective-part-i/' rel='bookmark' title='Permanent Link: 13 Years On The Web &#8211; A Retrospective, Part I'>13 Years On The Web &#8211; A Retrospective, Part I</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/03/ad-revenue-as-a-business-model-eat-dinner-first/' rel='bookmark' title='Permanent Link: Ad Revenue as a Business Model &#8211; Eat Dinner First'>Ad Revenue as a Business Model &#8211; Eat Dinner First</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.perplexedlabs.com/2008/11/20/13-years-on-the-web-a-retrospective-part-i/">Part I</a>, I detailed the formative phases of our web development careers.  A providential encounter with a magazine article, tons of free time, inherent curiosity, youthful ambition were the perfect storm that threw us into the world of programming.</p>
<p>At this time, Matt was admittedly more of a programmer than I was.  While our web "programming" skills were roughly equal, Matt was also into C/C++ programming.  He wrote an Asteroids-like game to teach his brother math, and he would dissect gaming engines like the one used in Doom.  At one point we even thought of developing our own first person shooter based on our neighborhood and school, the premise being, we had to rescue everyone from zombies and aliens.  Again, youthful ambition, and not a bit of naivety.  Sometime in 1995 or 1996 we registered our first domain name, perplexed.com, with a $100 investment from my grandmother.  The name "perplexed" represented everything about us at the time: young and curious, but sometimes confused about the state of the world we were in.  Why did people do certain (illogical) things?  What were we going to do with our lives when we got to college?  Will the Knicks ever beat the Bulls in the playoffs?  It is my contention that perplexed.com is the greatest domain name ever registered, and I cannot articulate how angry we are with ourselves that we didn't renew it. More on that later</p>
<p><img style="padding: 2px !important; margin: 0px !important; border: 1px solid #D6D6D6;" title="title" src="http://www.perplexedlabs.com/wp-content/uploads/2008/12/title.jpg" alt="title" width="350" height="150" align="right" />We decided perplexed.com would host two different sites: Matt's Game Programming MegaSite, and my VB Programming MegaSite.  This arrangement allowed us both to build sites related to our interests.  We tried to keep the layouts the same so we'd have a consistent design across the domain; two frames, the left being the menu, the right being the content.  The color scheme was black background with white text.  We tried to make all our images using PhotoShop.  They came out ok in a cheesy way, as you'd expect from two programmers.  GPMega would focus on all aspects of game programming, especially engine design and DirectX.  Matt had a ton of C/C++ code up, as well as tutorials, links, software, and even a MIDI player so you can listen to a MIDI version of Van Halen's "Panama" while you browsed.  VBMega was concerned with Visual Basic programming, and the main focus was on programs that you could use to manipulate earlier versions of AOL.  For example, posting ASCII art in chat rooms, knocking people offline, pinging the service every few minutes so you wouldn't get knocked off, as well as other more nefarious features.  I ran this portion of the site, which allowed me to learn VB programming while at the same time piss off my friends by booting them off AOL over IM.  Everyone was a winner!</p>
<p>We made money the old-fashioned way, by selling ad space.  We signed up for various banner exchanges before settling with 24/7.  They had a different name back then, I just can't remember what it was.  In any case, the sites both grew very quickly, and the checks were arriving.  The first few months we made $150, then $200, then $300.  At the high point we were pulling in $1500 a month, strictly through ads.  When you're 15 years old in high school and you're walking around with that kind of money in your pocket, you feel on top of the world.  While the rest of our classmates ate the cafeteria food, we walked over to the deli across the street and treated ourselves to bacon egg and cheese sandwiches.  Going to the mall was fun: your girl wants some lunch?  No problem.  New shirt?  Done.  New programming book?  Buy two!  One month, perplexed.com accounted for a little more than 1% of the total ad impressions for every site that advertised with 24/7.  We were experiencing impressive growth.  Perhaps the most stunning thing to happen to us during this time was one day when we were in CompUSA.  Matt was leafing through a book, <a href="http://books.google.com/books?id=lRUj-nhQRu8C&amp;pg=PP25&amp;lpg=PP25&amp;dq=game+programming+megasite&amp;source=web&amp;ots=7vBe3xL25D&amp;sig=g5P08vACy_GZkHJfP1Cy6pKFb-4&amp;hl=en&amp;sa=X&amp;oi=book_result&amp;resnum=4&amp;ct=result">Tricks Of the Windows Game Programming Gurus</a>, when he saw GPMega mentioned!  We didn't even know the author had referenced us.  It was shocking; we were open-mouthed.</p>
<p>Unfortunately, all good things must come to an end.  In retrospect, the way Perplexed ended is sad indeed, and the only way I can explain it is stupidity.  In October of 1998, my family and I moved to another town, which was only 15 minutes away from where Matt lived, but to two kids with no cars who would now be going to different schools, it might as well have been a million miles.  We kept in touch and continued to hang out, but it was hard to run the sites at the time.  So many of our ideas came from lunchtime brainstorming, playing ball after school, or Friday night coding sessions.  Now that we weren't seeing each other on a day to day basis, the importance of the sites and the partnership that created them began to fall.  It sounds insane in this age of telecommuting, but back then we didn't know any better.  And priorities changed as we got older.  When you get a new car and you're hanging out with your girlfriend, and doing whatever high school kids do, who wants to be up at 3am on a Friday writing HTML and answering emails?  The nail in the coffin was the failure to renew the domain name.  To this day I don't know why we didn't do it.  I can't explain it; it was a stupid decision and one of the biggest regrets of my youth.</p>
<p>At this point, Matt and I are seniors in different high schools, preparing to attend different colleges.  We're still great friends but the lack of face time has meant that our priorities diverged a bit.  It's worth mentioning that my grades were better in high school and college after I moved away.  I failed out of Advanced Math in seventh grade, but got A's in Calc I, II, and III in college.  Go figure!  In all seriousness, the fact that Perplexed.com is now part of an ad farm is a huge source of pain and regret.  But all is not lost.  Stay tuned for Part III, where I will bring the story up to the present time, and offer my reflections on the business and pleasure of web programming.</p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2008/11/20/13-years-on-the-web-a-retrospective-part-i/' rel='bookmark' title='Permanent Link: 13 Years On The Web &#8211; A Retrospective, Part I'>13 Years On The Web &#8211; A Retrospective, Part I</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/03/ad-revenue-as-a-business-model-eat-dinner-first/' rel='bookmark' title='Permanent Link: Ad Revenue as a Business Model &#8211; Eat Dinner First'>Ad Revenue as a Business Model &#8211; Eat Dinner First</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2008/12/19/13-years-on-the-web-a-retrospective-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get It Done</title>
		<link>http://blog.perplexedlabs.com/2008/02/01/get-it-done/</link>
		<comments>http://blog.perplexedlabs.com/2008/02/01/get-it-done/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 19:06:54 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[languages]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://perplexedlabs.com/2008/02/01/get-it-done/</guid>
		<description><![CDATA[Today's comic at xkcd was entitled "Real Programmers", which was hysterical. It got me thinking about a lot of blogs where flame wars erupt because fanboys think their current way of doing things is best, and yours is crap. Everyone has an opinion about which language/framework/web server/OS is The Best. It's fine to have such [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/18/php-drinks-java/' rel='bookmark' title='Permanent Link: PHP Drinks Java'>PHP Drinks Java</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/07/01/pythons-tornado-has-swept-me-off-my-feet/' rel='bookmark' title='Permanent Link: Python&#8217;s Tornado has swept me off my feet'>Python&#8217;s Tornado has swept me off my feet</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/02/08/deployment-using-capistrano-and-webistrano-via-rails-and-phusion-passenger/' rel='bookmark' title='Permanent Link: Deployment Using Capistrano / Webistrano via Rails / Phusion Passenger'>Deployment Using Capistrano / Webistrano via Rails / Phusion Passenger</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Today's comic at <a href="http://xkcd.com/378/">xkcd</a> was entitled "Real Programmers", which was hysterical.  It got me thinking about a lot of blogs where flame wars erupt because fanboys think their current way of doing things is best, and yours is crap.  Everyone has an opinion about which language/framework/web server/OS is The Best.   It's fine to have such opinions, and to be able to explain and defend them.  But please don't tell me I am somehow less of a programmer because I use That Other [language/framework/web server/OS].  In a professional capacity I use Ruby on Rails everyday, and I love it.  But I have no problem writing applications in PHP, Java, C/C++...even VB.  Because at the end of the day, users, be they business or otherwise, only care about one thing: the end product.  As programmer, I use whatever tool is best to get the job done.  Of course I have my preferences but I will never try and force a solution to fit within those preferences.</p>
<h3></h3>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/18/php-drinks-java/' rel='bookmark' title='Permanent Link: PHP Drinks Java'>PHP Drinks Java</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/07/01/pythons-tornado-has-swept-me-off-my-feet/' rel='bookmark' title='Permanent Link: Python&#8217;s Tornado has swept me off my feet'>Python&#8217;s Tornado has swept me off my feet</a></li>
<li><a href='http://blog.perplexedlabs.com/2010/02/08/deployment-using-capistrano-and-webistrano-via-rails-and-phusion-passenger/' rel='bookmark' title='Permanent Link: Deployment Using Capistrano / Webistrano via Rails / Phusion Passenger'>Deployment Using Capistrano / Webistrano via Rails / Phusion Passenger</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2008/02/01/get-it-done/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
