I was disappointed that I missed the Ondina launch for the 6th, so I decided to channel that disappointment into coding power! Little did I know that would take me on a 40 hour binge of coding and internet frolicking. I feared the worst this morning after I awoke: “What disastrous code did I write?!” Surprisingly, aside from quite a few profane variable names, the logic was sound. In fact I produced a lot of code, but written in a different way that I would have normally produced. It’s like reading over code by another developer where you agree with how they wrote it, but would have written it differently yourself.
There were some things that needed fixing. When I reviewed the commit messages this morning I had a hard time figuring out exactly what I had written. I knew it was for the DNS administration section because I remember making the video for it at 3AM. However, the commit messages would have you think otherwise:
34tf000 DELETE DELETE DELETE cfdae81 I'M A TIGER!!! 5a1f065 DUHHH YOU NEED MORE AJAX 895612f I'M HAVING A GOOD TIME!!!! d851f46 DON'T STOP ME NOW! 45fe891 Integration of API shit e4cda3b Moving forward to 0.5 as when DNS completes we'll be a 0.5 release 29e6061 No ID is required 3b58f33 Added updated styles for controls and dropdown ee0677b Created DNS module and basis 77c08aa Merge branch 'dev' of code.ondina.co:ondina/cp into dev 620cf7e small comment ac3fdc9 affects-me-button for the outstanding reports list in the feedback form? 9b3639f fixed the input class for width 7700967 Fixed weird submit buttons |
These commits seem to correspond to, what Last.FM confirms, is an over hour long repeat of Queen – Don’t stop me now.
After doing some rebase magic in Git these commit messages are actual useful. The last cleanup was with code comments. Interestingly enough I was compelled to write detailed descriptions of what I was doing on every other line – as if alert and awake self couldn’t figure it out!
In all I had a lot of fun working with that much code in that amount of time. I don’t plan on doing this again for quite some time but I think it would be fun to do again. It’s amazing how energizing not sleeping can be.
As I slowly make my way back into personal coding projects and releasing OpenSource again I’ve decided to publish my Standards of Development.
Standards help keep code clean and consistent while adhering and enforcing to best practices and high quality. For most languages there is no required layout for code so below is the one I employ for most projects and languages.
When I write code most of my code structures follow the Allman style indention scheme with some slight modifications. Tthis is probably going to be the biggest upset as a lot of people prefer the K&R style variant 1TBS. This is probably as fundamental an argument as Vi and Emacs (I use nano – so there) the only difference is no one else is affected if you use Vi or Emacs – in source code though, hard shifts between 1TBS and Allman will cause quite a few eye soars. So it’s important before you start a project to agree on a standard for writing the code.
Here’s a basic code example
<?php /** * This is a test file * * @author Marco Ceppi <marco@ceppi.net> * @package Example */ /** * Class Name * * It does STUFF * * @author Marco Ceppi <marco@ceppi.net> * @package Example * @subpackage if-required */ class Class_Name { public $an_array = array(); public $first_variable; public $second_variable; /** * Class_Name Constructor * * @param string $param1 * @param string $param2 * * @return void */ public function __construct( $param1, $param2 = 'default' ) { $this->an_array = array('first' => 2, 'second'); } /** * Do Something * * Additional details about what this actually does * * @param string $param1 * * @return mixed Details about what is returned */ public function do_something( $param1 = NULL ) { return $this->_processThat($param1, $this->first_variable); } /** * Process That * * Additional details about what this actually does * * @param string $param1 * * @return mixed Details about what is returned */ private function _processThat( $param1, $param2 ) { // Do something! if( $is_this ) { // Do that } else if( !$is_other_thing ) { // Doing this } else { // Gave up? } return $results; } } |
A quick break down.
Each method, the file, and the class is documented using phpDoc format. If you’ve used Oracle’s javaDoc or any similar document templating system then most of the Syntax will be familiar. If you’ve never really documented code before consider this a wake up call.
Naming schemes are as equally important when writing code. Using a set standard continues readability of code. When creating names for methods, functions, classes, and variables the names should be as short while descriptive as possible. If a variable can not reasonably be named in less than ~15 characters it should be abbreviated as best as possible and a comment left above it’s first occurrence in the page detailing what it’s full name should be.
While most projects typically go with either CamelCase, pascalCase, or under_score I’ve found a combination of the three to be effective in typecasting methods and variables. For starters class names are always first letter capitalized with underscores replacing spaces.
class User_Session {} class User {} |
Variables are all lowercase with _ replacing blank spaces
$username; $post_id; $multiple_worded_variable; |
When naming functions and public class methods the same format for naming variables should take place.
function process_request( $req ) {} class Generic { public function start() {} /** * Prepare Database Hook */ public function prepare_db_hook() {} } |
Finally the special cases which operate outside of the norm – Private and Protected scopes. I always treat these special when writing classes and objects. The shift from a normal naming scheme allows me to easily identify that they have a special ruleset applied to them – typically this naming scheme follows a _pascalCase format while adhering to the “15ish character” rule.
class Generic { protected $_variableName; private function _secret() {} protected function _getDetails() {} private function _setUpdateRules() {} } |
Whether it’s an if, elseif, for, foreach, while, or switch the same general Allman style indentation applies. Parenthesis should be attached to the control structure and a blank white space should pad the open and close parenthesis at the first level. Further embedded parenthesis should hug their contents.
These follow near the same formatting in regards to parameter acceptance.
if( !$is_active ) {} if( ($user_id > 20 && $is_new) || !$is_active ) {} while( $true === true ) {} foreach( $array as $key => $val ) {} |
With a switch each case starts and finishes on it’s own line on the same level. The default case should always be included regardless of use and should always be terminated with a break
switch( $mode ) { case 'first': // Contents break; default: // Fall back break; } |
The for loop should follow the same constraints as the above control structures, however I wanted to take a minute to highlight a best practice when creating loops.
Most for loops are iterating over an Array and performing various computations against it. What I see a lot, and want to stress is not best, is placement of the objects count in the evaluation portion of the loop. For loops are structured by for( LOOP START; EACH TIME; END OF EARCH RUN ) having a count executed each time the loop completes adds execution time to the script. Instead prepare everything in the loop start.
$roommate_names = array('Jim', 'Marco', 'Sara'); for( $i = 0, $total = count($roommate_names); $i < $total; $i++ ) {} |
Or just perform the count outside of the loop. Typically I avoid for loops at all cost deferring to its cousin foreach unless there is no other possible solution.
This is a living document last updated 2011-04-05 4:00PM EDT
To continue my crazy development schemes of abstracted goodies I’ve found the following code slice to be of particular interest:
class test { public $fubar; function __construct() { return true; } function Foo() { $this->fubar = "bar"; } function Bar() { $this->fubar = "foo"; } function __toString() { return "Value: " . $this->fubar . ""; } } class nack extends test { function __toString() { return "NACK QUACK! " . $this->fubar . ""; } } $classname = array("test", "nack"); foreach( $classname as $classy ) { $runtime = new $classy(); $runtime->Foo(); echo $runtime; $runtime->Bar(); echo $runtime; } ?> |
The results should be:
Value: bar Value: foo NACK QUACK! bar NACK QUACK! foo |
This demonstrates creating and running classes from variable names, something I’ve had to hack away at recently. Since the names are also stored in array form you could even go about creating a “trigger” like mechanism and do an array_walk (example assumes the class definitions are intact):
function runtime_name($item1) { $runtime = new $item1(); $runtime->Foo(); echo $runtime; $runtime->Bar(); echo $runtime; } echo "Walk it out!"; array_walk($classname, 'runtime_name'); |
The results of which look a lot like this:
Walk it out! Value: bar Value: foo NACK QUACK! bar NACK QUACK! foo |
This method would allow you to re-use that “logic” multiple times throughout your program.