Ruby & Project Realisations
Labels: Hacking, OOP, Pascal, Perl, Professionals, Python, Rexx, Ruby
Labels: Hacking, OOP, Pascal, Perl, Professionals, Python, Rexx, Ruby
Labels: Arc, failed language implementation, Lisp, Paul Graham, Perl, Python, Robert Morris, Ruby, Scheme
Labels: Agile, Cheetah, Perl, Python, Rapid Application Development, Team Projects, Templates
As was mentioned in a previous entry, I stated that I was willing to try being an independent contractor again sometime. That time is now. As such, my new corporate overlords are a media publishing group and I’ve been called in to do a ground up architecture and engineering job, along with continued long term maintenance. Unlike before this situation appeals to me because it lacks on of the most common issues in the realm of development in general, legacy upkeep. Sure, there is the little issue pertaining to a php application which needs to be put on a website short term, but after that we’ll be trying to limit php to specific applications on a limited (only as-needed) basis.
Ultimately we’re looking at starting with a fresh new remote server and that being said, my own experience brings me down to a quasi LAMP setup. Traditionally I’ve found that when I want a rock solid remote host, one which I know can go years on end in a reliable manner, I chose FreeBSD. Nothing against Linux other than I find it fine for a Desktop or a Server, but more so the desktop than the server. I find that there still is no substitue for Apache when it comes to matters related in pushing out pages to the web.
Next is a point of contention, the database. I’ve been using MySQL since version 3.23.24a (or something around that revision number), and have found that it met my needs about half of the time. Much of it (at the time) revolved around the issues pertaining to MySQL’s myisam faults and weaknesses regarding concurrence in high insert/update environments. I know some people out there (many actually) will start arguing this point right away, and I still say unto you that this is a known weakness. The myisam database storage engine is designed for speed, not high-concurrecy, nor transaction safety. When paird with the InnoDB engine, and the removal of the auto-commit flag (as it negates the whole point of using a transaction safe engine), most of those issues disappear. The other issues pertain to foreign keys, store procedures, etc., which have been slowly addressed in versions since the 3.xx base. Now we’re at the 5.xx family and much has improved.
However, all of these points still cause MySQL to pale in comparison compared to PostgreSQL. True, MySQL has proven to be very capable and very popular, especially among the Linux crowd and cheap hosting crowd. I will be installing MySQL on the new machine to handle support of third party web applications, though when it comes to hosting any important data, there can be only one choice, and it isn’t MySQL. PostgreSQL is the clear winner here, the closest db engine we have to Oracle without being Oracle.
Finally, we approach the last letter in our acronym. The ‘P’, which can stand for a multitude of langauges scripting, web and otherwise. We have PHP which is wonderful for quick and simple (an a handful of not so quick and simple) web based applications. It is an easy language for the novice to learn, and in the hands of an expert, even more so capable, though it has its faults, and among those security being the top. Much effort has been made (especially post 4.2.3 and 5.x versions/trees, and I hope to see this evolution continue, though I still don’t see myself using it much as I don’t feel compelled by the language as a whole.
Next we move to another ‘P’, which in actuality is a ‘p’, perl. The oldest of the languages we’re discussing here, but not by that much of a time frame. Perl grew out of the personal needs of a C programmer, Larry Wall as a combination replacement of both sed and awk (amongst other Unix utilities). I’ve been paid to code in Perl for the better part of the past 11 or so years, and I can say after all of that time several things. On the good side, perl is found everywhere, has a large code base, and is fast. On the bad side, I’ll have to limit my dislikes and faults found within perl so that this entry doesn’t go on for thousands of words. Limiting my issues with perl we will see that it allows, almost seduces people into writing ugly, cryptic code. Yes, yes, yes, the code some perl monks/mongers write may be very crafty. Crafty does not equate with great, let alone good quality.
All too often we see people referring to the TIMTOWDI (There Is More Than One Way to Do It) mindset of perl as being a benefit, though I see it (time and time against, countless of codebases later, even the CPAN library) as being a flaw and weakness. If you don’t enforce a certain level of clean design into the language itself, you end up with a mess, or as many others have stated, a write-only language, one which even the author(s) of programs cannot read/decipher down the line. My suggestion is for perl coders to follow Java coding guidelines. I mean, we’re talking about a language that doesn’t has several decent levels of rules and coding enforcement (such as the ‘use strict’ pragma), but is so foolish as to allow people to code in a manner contrary to that pragma when it already exists in the core language. How about a proper exception handling system? Eval blocks or non-core/second-class libraries do not make a proper first class handling system. This is asinine in a language that has been around for over 20 years as of this writing. I could go on, but I’d rather not.
This brings us to a non-p ‘P’ in LAMP, Ruby. Ruby to me is an evolution of perl in many regards, especially its object based design and proper exception handling system, however it still fails miserably in the sense of massive overuse of tokens and pascal-esque verbatim block terminators. Rails has made Ruby a mainstream language, and I do feel that it has considerable potential ever more so than Rails alone, but it still has a ways to go when it comes to speed and cleanliness. Matz has be working hard on it, and I’d like to think there are great things ahead for the language from the land of the rising sun, but at the current moment, I still find it lacking as non-web specific development platform.
Finally we come to where I’m heading, and I’m sure others have already figured that one out. Python rounds out the last ‘P’ in the equation. Python is almost as old as Perl, and is rooted in development languages as opposed to the shell and various utilities. In this language we see a very capable, 100% object-based development language which is capable of handling coding projects of any size which espouses clean design, human readability, code re-use, distributable byte-code compiled classes/applications and proper exception handling as a first class citizen.
So as we can see where, the solution i find most reliable and long-term maintainable with minimal development time, maximum return for design/coding efforts, security and platform flexibility is simple. So it isn’t technically a “LAMP” solutions, more as it is a BAMPP solution encompassing BSD for the OS, Apache for the web serving, MySQL and PostgreSQL for the database(s), and Python for application development.
I came to the above choices after years of experimenting and experiencing and I do suggest others experiment on their own if they have that luxury/time frame available to them, but I do offer the above as a recommendation as I would (and have, and will) bet my own future livelihood on the flexibility and reliability of the aforementioned combination of technologies.
Labels: BAMP, FreeBSD, InnoDB, LAMP, MySQL, OS, Perl, PHP, Python, Ruby
I’m not sure as to whom to attribute the following statistic, but i believe it was something along the lines of this; Code is read vs. written on at a 10:1 ratio, meaning that the is far more reviewing of any specific codebase than there is writing to said code. Furthermore, the majority of software positions involve maintaining and modifying existing code as opposed to creation of new code from the ground up.
To what does all of this allude? The importance of writing clean code. Knowing full well that other developers are going to have to read, understand and most likely modify your code in question at some point(s) in the future. This is where our responsibility as software professionals (even in the case of hobbyists) comes into play.
Several languages have tried to address this problem by intrinsic design decisions. Most notably among those in recent times are Java and Python. Java does so by its explicitness by design, and Python by its forced formatted a la the whitespace requirement. Both are effective in what they do, however there are still a multitude of ways in which both can be written in a harder to read format. Obviously choice of variable, function, class and object reference names is a very large point of readability (or not) which really cannot be enforced by a language specification. Let us take a look at this very issue and while we’re at it, i’ll be clear that this is not a Python vs. Java issue discussion.
All too easily so many coders (I know this from having had to look at, understanding and refactor their code) overlook one of the best sources for building readable code, and that is their naming convention. There have been several best practices and coding style specifications documents produced that one might think me as flogging a dead horse, but I assure you this is not the case.
In the following examples we see a variation of languages and how we might commonly see the same variable name referenced (and initialised as it were):
Smalltalk:
num_of_doors = 4 ;
Python:
numberOfDoors = 4 OR numDoors = 4 OR number_of_doors = 4
Ruby:
numberOfDoors = 4; OR numDoors = 4; OR number_of_doors = 4;
Java, C#:
int numberOfDoors = 4; OR int numDoors = 4; OR int number_of_doors = 4;
Lisp:
number-of-doors := 4;
C, C++:
int intNumDrs = 4; OR int num_drs = 4; OR int int_drs = 4;
Perl:
my $vzoiuwriozufsd = 0x04;
The point here is that there are many varied ways in which the same variable can be referenced. I am of the opinion that much along the lines of Guido van Rossum of Python (and to a lesser extent ABC) fame, that there really should be one and only one obvious way to do it. This isn’t to say that I think everyone should code in the same language, and speak the same tongue, etc. What it does mean though, is that to be understood by others (and sometimes by ourselves), we need consistency, and unless we have a set of strict guidelines set out for us as software engineers, developers, etc., we might as well code in our own made up dialects.
I am of the opinion that a proper interpreter, compiler, virtual machine, etc., should be more than capable of quickly turning long variable, class, function and method names into concise tokens with small internal footprints. So much to the point that there is no excuse for not being verbose. At one point in time, every single byte of allocated memory for names of the aforementioned items was a crucial issue which required extreme concise naming conventions to be followed. Those times are gone in this day and age, allowing us to be clearer and more expressive.
I can see using single letter counter variable names, but never could I imagine naming a class, method or function in such a sparse manner. I like to think that clean code reads somewhat like a choose your own adventure book, were it to have a greater variety of options available. Functional or Object Oriented is immaterial here, as cleanly written code isn’t tied to a specific construct or paradigm. I think most of the following rules are applicable to pretty much every language out there. Emphasis below pertains to items that I feel are not language specific guidelines.
As can be seen, most of the above are applicable to languages other than Python. I find myself at my current place of employment having to deal with the problems for which this list addresses. Much of what I’m doing is updating a legacy code base that is literally plagued with dozens of individual programs and modules that are blatant attacks on decent code. They (collectively) single-handedly break most of the above guidelines.
First off it is almost entirely written in perl, which instantly shoots down the Readability counts factor (and no, it wasn’t done with the strict pragma, and yes it uses a bunch of requires and plenty of global variables).
Secondly, errors don’t pass silently because there is no built-in exception handling in perl. Evals of code blocks does not equate to a proper exception system, nor does an add-in module. Exceptions are something which need to be a core part of the design of the language, and perl falls far short of the bottom of the heap on this issue alone.
Thirdly, when one is expected to maintain code in an environment wherein the expectation is to follow the existing coding schema as it were, with global variables, no exception handling, etc., it truly becomes a daunting task because one must force his/herself to think ‘wrong’. The logical and/or proper solution that is naturally though of as a solution would only lead to reprimand, simply because trying to think in such a manner will produce mistakes, primarily because trained seasoned professionals don’t think in the same manner as the less experienced coder(s) responsible for the legacy code int eh first place.
Finally, (I’ll leave it to three to be nice to those few perl hackers who’ve read this far), after ten plus years of coding in perl, I’ve come to learn that the TIMTOWDI (There Is More Than One Way to Do It) mantra of perl is one of the biggest problems that arise from the language. It is this careless and dare I say reckless mindset which has led to so many atrocities in the professional coding world.
My point is simple enough to follow. Write readable code, as it is a defining factor as to how far you’ve matured in the field of software development. It doesn’t necessarily mean you are even that good at what you do, but what it does do is show how you understand a rudimentary problem that so many others have failed to realise. Readability Counts, and without it, we are truly lost.
Labels: Amateurs, C/C++, Design, Java, Lisp, Perl, Professionals, Python, Readability, Ruby, TIMTOWDI
This whole 'ordeal' with Java has been going on with me for something over 7 years. I started teaching myself Java way back when, but found it to be utterly too verbose for productivity, opting for perl in its place. Then perl very quickly proved to be lacking when it came to large projects, and code cleanliness (by design mind you, I have written production code which after 7 years upon seeing it again, was very easy to follow in spite of its 7,000+ line codebase), and utter hackishness about it, regardless of the raw power. I moved to Python both personally and then shortly thereafter, professionally where I enjoy myself most.
However, there are certain things I've come to realise over the past many years, more so over the past few specifically. One is that I should force myself to code in one of the behemoth languages to the point of solid fluency regardless of how dreadfully painful it can be. Two is that most jobs are hybrid these days and require a wider set of disciplines in terms of technologies, languages and toolsets than in the past, and whilst I don't have any need for Java in my current work endeavours, it doesn't negate said need in the future. Three is that Java makes the most sense being that C/C++ are for all purposes outside of hardware tied code (such as operating systems, device drivers, compilers), dead for application creation, period.
And so it is that I venture forth again into the wonderful realm of re-re-learning the evil behemoth formerly known as oak. May she not be as cruel a mistress as in the past as my understandings of her workings have been greatly enhanced thanks to python sharing so many of those conceptual designs and paradigms coupled with my adoration for the latter language.
Wish me luck.
I've always found it interesting reading about coding paradigms and what not, including ways in which a coder can increase his/her throughput. Meaning, how can I quickly pump out software that is easily portable, eloquently written, and easily maintainable by either myself and/or someone else one, two, six, eighteen months down the road?
I've found out the answer to that question, in the form of a language, and it isn't Perl, Java, or Ruby. Simply put, it is Python by Guido van Rossum. The language that I loved to hate for so long due to what was perceived as a nasty control freak mentality regarding white space sensitivity, and the "lack" of freedom of being able to use {'s, ('s, ['s and ;'s anywhere I wanted.
I've been using Python as mentioned previously in this blog for both large professional projects as well as certain other miscellaneous personal object-focused projects of mine and about two years ago when accepting a one-off project outside of my normal employment environment, I decided to try utilising my new favourite language for professional work. I must say that it was indeed a very simple program that I could've easily written in Perl, but no where as cleanly as in Python. The standard python libraries/classes included with every distribution (including as a stock install on my OS X 10.3 Panther equipped Apple Macintosh G3 iBook which I was using at the time) made it a clear choice (at least to attempt).
The premise of the program was amongst the most simplest of tasks. The client has a Microsoft Frontpage created website with a form. It currently points to no where because the individual doesn't know anything about capturing form data, so that's where I come in. All that is wanted is for all of the fields to be commingled into an e-mail to be fired off every time someone submits that form. He doesn't initially even want data format and/or content checking, but I inquired anyway (I'm not some code monkey who doesn't try to analyse what the non-coder *really* needs/wants/means).
The code itself took a matter of about 15 minutes to write down, organise and test. The code is more than fifty-percent blank lines and/or comments. Using the standard smtplib and cgi libraries/classes, this turned out to be an absolute breeze. The advantage of easily stepping through the dictionary (hash) produced by the cgi.FieldStorage() method was a cinch thanks to the built-in cgi.has_key() and cgi.value() methods.
While this is hardly an example of actual RAD, or any detailed work for a language such as Python, it does give a simple real world example of why I will continue to push for the use of this language. What I wrote worked the first time I wrote it, without any errors. I reads like pseudo-code and it was enjoyable to write because it flowed so easily from my mind into Python's very natural syntax. I used to espouse Perl for such things, but in comparison, I find it difficult to think that I held Perl in such regards for natural syntax.
This doesn't mean that I'm a one language only person. Much of the application infrastructure I've produced at my current (and previous) employers' establishments I design and implemented in Perl on a multitude of Linux and/or FreeBSD boxes. This has changed as I've moved to a FreeBSD centric platform layout, with the intent of someday using Python as the shining star for any medium to large implementations, and let it share the small jobs with a mix of Perl and Bash scripts.
I only wish I could get others to give Python a fair shot as it truly is one of those languages that deserve a second look, it may just changed your entire perspective on how you code.
Labels: BSD, CGI, Coding, Design, Java, Objects, OOP, Perl, Python, Ruby
Now that a little over a week and a half has passed at my new place of employment, I find that I understand my new environment enough to make some observations in a not-too-specific manner out of respect for my new employer.
First let me state that all of the existing software is a product of its environment and that it all functions as it was intended. That being said I’m able to say with a clean conscience (after that little preamble) state that the code was ... lacking.
I am thankful for this to some degree. For one thing it provided an opportunity for employment at a place I enjoy with some very intelligent individuals who all seem to have their own special abilities and areas of expertise.
More importantly though, I’m thankful because it places me in a situation I find most mentally stimulating. It makes me re-think an entire existing architecture and being that I have held the role of Software Architect (amongst others) for much of my professional life, it is all the more appropriate.
It is one thing to walk into an new environment with a clean slate in which one may design to their heart’s content, yet another wholly different situation when the software exists in a production environment of one form or another. There are so many more facets with which to deal when the database structure and all of the depending software is tightly build upon that aforementioned code base.
The whole point of this rambling is that my first week and a half has passed and while I have done much more with the database redesign, class design, object handlers, etc., I have finally been able to enjoy that great feeling which comes when turning previously un ‘strict’able perl code into a fully compliant piece of code. I might also add that I ensured the code conformed within the guidelines of Damnian Conway’s “Perl Best Practices” book, which while a little different than my own manner of laying out perl code, is wonderful none the less.
Now that this honeymoon is over, I can move onward and upward to greater code causes to champion, and based upon the intents of the owner of the company I don’t doubt that there will be a wonderful logic requiring plethora of future projects for which I am to contend. I only hope that others out there are as lucky in their endeavours.
Labels: Bad Design, Best Practices, Coding, Methodology, Objects, OOP, Perl, Strict
My recent procurement of new employment has thrown me back into the hellish world of perl. For those unaware, perl is the dyslexic ginger stepchild of 2400 bps modem line noise, albeit executable and fast. Now don’t get me wrong, I’ve been coding professionally in perl since 1995, and have produced several large enterprise applications that are still in use to this very day.
Perl is a very capable language without a doubt however having used the language for so many years both professionally and for hobby I have become well aware of its faults and shortcomings. This article isn’t specifically about pointing out the many issues perl has, some of which will be addressed in Perl 6 (when it eventually gets released in 2027). Today I am only going to speak of one specific issue which is actually quasi addressed in a set of modules, all relating to the Template Toolkit.
When coding in perl, even adhering to best practices such as those outlined in the excellent book by the one and only Damien Conway, author of the more notable “Object Oriented Perl”, one still finds perl problematic due to too much adherence to the ‘there’s more than one way to do it’ mantra. The constructs are very low-level language based, which makes sense given perl’s humble beginnings but ugly none the less. Some languages which have come into existence after perl have corrected this shortcoming and as previously stated, perl is moving towards correcting some of its ugliness, though a bit late.
The current leading language which not only matches perl’s power in many areas, while exceeding perl’s abilities in others is Python. Its focus on clean form through visually enforced coding constructs along with a more natural syntax which closely follows not only spoken speech but though processes is a testament to language advancements. Which brings us to my main focus of this article, clean syntax in the style of Python, within a perl application.
The perl Template Toolkit by Andy Wardley is the definitive all around powerhouse of template creation systems available within perl. There are many others available but they all pale in comparison especially when you take into consideration the multitude of uses, formats and arenas in which Template Toolkit is competent. This is no mere mail merge replacement library, even though it will do just that exceedingly well. The toolkit is much more than that, mainly due to its wonderful flexibility in its meta language utilised for in-template logic.
This language within a language is also where I happen to draw its direct link to Python whether intentional or not. Good design shines through and it just happens that the aforementioned comparison is dead on. Let us begin with a sample of what I’m talking about but reviewing a simple .tt template from the Template Toolkit website.
[% FOREACH team = teams -%]
[% team.name %] [% team.played -%]
[% team.won %] [% team.drawn %] [% team.lost %]
[% END %]
All of the above would be located in a .tt template file. A dictionary (a.k.a. associative array/hash) is passed called “teams”, containing the named elements of name, played, won, drawn and lost respectively with their associated values. Unlike perl’s “c” style referencing methodologies which is fine and dandy for shell scripting or c programming it is by no means as clean as the more appropriate referencing styles utilised by most modern languages, specifically object oriented languages using the dot format. As a side note, perl’s object system was ripped almost verbatim from Python, though poorly implemented (e.g. implemented with perl’s tmtowtdi mind-set as opposed to a proper object focus with structure and stringency.)
The above code is clean and simple, much like Python. The only exception is the punctuation, which is only necessary as delimiters for the meta language. Thanks to this cleaner approach taken by the Template Toolkit system, we can allow the logic to be cleaner by limiting the perl to only the minimal amounts thus ending up with cleaner overall code, especially handy in the world of cgi and/or form processing.
Let us face facts, of the following, how would you range readability from easiest to hardest.
Python:
for team in teams:
print team.name, team.played + ‘-’
print team.won, team.drawn, team.lost
Template Toolkit:
[% FOREACH team = teams - %]
[% team.name %] [% team.played -%]
[% team.won % ] [% team.drawn %] [% team.lost %]
[% END %]
Perl:
foreach my $team (@teams)
{
print “$team{‘name’} $team{‘played’} -\n”;
print “$team{‘won’} $team{‘drawn’} $team{‘lost’}\n”;
}
The above Python code is simple to understand, even by non-programmers. The Template Toolkit version while a little messier due to the punctuation is still rather clear cut and simple to read, while the perl version adds a significant amount of unnecessary punctuation. What this all comes down to is that if you have to code in a perl environment, there is now a way in which you can produce a cleaner codebase, mainly by keeping the data display layout and logic within .tt template files.
So I commend Andy Wardley and all of those who assisted with this wonderful module (and its associated add-ons) in doing what Larry Wall and crew have been unwilling to do thus far within perl. Dictate flexible standards which avoid the ugliness which has now grown synonymous with perl. If you find yourself stuck in a perl environment, you now have some solace in a place to take refuge courtesy of the Template Toolkit.
Oh, and for those of you who have moved on to one of the the languages of choice at google, Python, there is the ever flexible Cheetah template framework.