First principle of code review: Check Yourself At The Door

<< Previous Article: 'The Principles of Code Review'

For years, I looked forward to reviewing someone else's code. I looked forward to pulling out the scalpel and dissecting the lines of their code to find a better algorithm, to find a better structure.

For years, some of my code reviews descended into arguments over whose approach was better. For years, most of these arguments ended with the code unchanged, the developer ever more convinced of how correct his code was, and further convinced that I was a fool. I'm sure he thought that. After all, that's what I thought of him.

For years, when someone reviewed my code, I would behave the same, too. I would defend my code, I would justify its existence, like a defendant making a submission to the court. And, more often than not, I would stick to my guns. I still do. I can't help it.

The mistake I made when doing code reviews was a basic one: I assumed that the quality of my code review was also the quality of my expertise. If my review was bad, and missed things, then that reflected poorly on me, not on the coder. Which is why I was precise and nit-picky. I didn't want to miss anything and look stupid.

Anything that looked unusual to me was pointed out, and I tried to make it less unusual. Which meant instructing them in how to code in my style, because that's what I was most familiar with.

That's all fine, except for one thing: a code review isn't about me. It's about the code. My job as a code reviewer is to make sure they have written something that accomplishes the job. Not something that accomplishes it in the way I think it should.

Leaving your ego at the door isn't going to help you make a wiser code review. But it will stop you from trying to convince someone that your approach is better. If they disagree at first, that's their problem, not yours. There are few times when good developers disagree with a recommendation that is obviously better. People disagree when the improvement is more a matter of opinion. If you come to the table with your ego, many of your recommendations will be loaded with your point of view, not your technical knowledge.

Your job as a code reviewer is simple:
  • Offer factual observations, not opinion of style. Observe possible division by zero errors, not better organization of the division algorithm.
  • Don't get bogged down on better names of variables (unless everything is named $a, $ab, $iii ...). Don't get bogged down indentation. Don't get bogged down on brackets. Don't get bogged down switches vs conditionals. A code review is not the place for style reviews. A code review is the place for making sure it does what it's supposed to do, in a way that's maintainable. End of story.
  • Don't reinvent their approach. If they way they coded it doesn't violate basic principles of coding, don't call them on it.
  •  Ask yourself one simple question: is my suggestion based upon my opinion of how it should be written and, if so, why is it better than his opinion?

When you review the code, keep your eye on the ball: you are making sure the code is correct, not that it does it in the way you would do it yourself.

Next: The Second Principle of Code Review: Understanding the Code

Why am I not getting back the correct id of my insert on an auto_increment table?

Oh, lovely MySQL. Everyone loves you and everyone forgives you for your subtle insanities. Like auto-increments.

If you have a table that is auto_incrementing, the id of your insert is returned using LAST_INSERT_ID(). This works jim dandy when mysql determines the id. If, on the other hand, you are so presumptuous as to overrule mysql and set your own value of the primary key, then the database goes and pouts in a corner.

mysgl> create temporary table test( id integer not null primary key auto_increment);
mysql> insert into test values (null); select LAST_INSERT_ID();
|                1 | JUST as we expect. Life is good ...

mysql> insert into test values (null); select LAST_INSERT_ID();
|                2 | Things are going good ...

mysql> insert into test values (33); select LAST_INSERT_ID();
|                2 |  !! WTF! 

mysql> insert into test values (null); select LAST_INSERT_ID();
|                34| !! and now we're back to normal!

For more discussion of LAST_INSERT_ID() gotchas:

Symfony logging tutorial

Symfony logs can be a very helpful tool when you are developing and/or testing.

Writing to a symfony log

The dev log file is written to whenever any code in Symfony writes using the Monolog service (in the dev environment):

$this->get('logger')->info("hello world");

Type the following command in a terminal, and it will watch the dev log file, spitting out the contents of the log file as the contents are written.

tail -f PATH_TO_YOUR_APP/logs/dev.log

Things to know about the Monolog Service

There are some behaviours with logging using the Monolog service you should be aware of.

  • when in production, logger->info() messages are simply discarded (for performance)
  • when in production, logger->err() messages can trigger emails, indicating the message being logged
  • when in production, if logger->err() is called, monolog *will* write any logger->info() messages to the prod.log file, that were leading up to when the logger->err() was called
  • when *not* in production, logger->err() and logger->info() write the error into the corresponding test.log or dev.log file
  • logging with monolog is like writing a trace of activity in the application (take a look at the existing log files, and you will see what I mean)
  • use it when a critical error occurs, and you need to be notified immediately
    $this->get('logger')->err("the database is not responding");

For information on configuring Monolog to email production errors:

For information on Monolog and Symfony:

The Four Principles of Code Review

Introduction: Happy Father's Day, It's An Algorithm!

If you're reviewing somebody else's new code, you better be doing it on eggshells.

The autistic developer is in love with his code. He treats every program as a child, and hopes for nothing but a long and stable future, one in which his program listens to everything the coder says.

That rarely happens: programs are like little children: they grow older and turn into teenagers. They become trucculent, sullen and sulking. They start to think they know more than you and they start to answer you in that way. I know you wanted me to return an array, it will say, one day, but you're so out of touch with the way things are, that you're wrong. I'm going to send you back a literal. Deal with it, dad.

It's not the fault of the code. It's the fault of the programmer, who loved his child too much, who created it and adored it so much he refused to recognize all of its flaws. And he could never quite fix the ones that he left to be fixed or found tomorrow.

You may be unlucky enough to review code after its birth. You may be so unfortunate, that the proud father will present you his bundle of joy, his creation, his work of art, and he will say to you, 'please code review this.'

What he means is, 'please tell me how beautiful my baby is.' Now you're stuck, because what kind of a pompous ass crititicizes a newborn baby?

When reviews of brand new code happen, no one listens to criticisms, because no one truly believes there could be something so wrong with the code that they didn't see the problem themselves. The developer thinks, the problem isn't me, it's the code reviewer: he just doesn't get it.

So good luck with it. Because when you are the code reviewer, you probably don't get it. Few people do.

Next: The First Principle of Code Review: Check Your Ego

Bash history commands

A few commands to mess with your shell command line history:

If you want to: Then you just type Notes
View the last N commands you ran$ history N
Erase all shell history$ rm ~/.bash_historyYour commands are normally stored in a hidden file called .bash_history, in your home directory.
Turn off the logging of history for your terminal session$ unset HISTFILE
Run a command without it being recorded in the historyAdd a space BEFORE the command.

Log commands in a different file$ HISTFILE= path_to_file/name_of_file
Record the time of a command$ HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S"

why 'event.preventDefault();' is better than 'return false;'


If this method is called, the default action of the event will not be triggered. You should try and use this instead of "return false;"

Return false is actually doing three things when invoked:

  1. It invokes event.preventDefault(), which is what you wanted.
  2. It invokes event.stopPropagation(), which may be what you wanted. But any other click events in (for instance) wrapping divs won't get fired.
  3. It stops callback execution and returns immediately when called.

Another example:

  // custom code
  //but this line causes a runtime error
  return false;

Whoops, if you throw an error before you hit return false, you are rolling the dice, because the return false never executes. What happens if the click function is attached to a form submit button? You will submit the form. That's probably not what you want.

Now try this:

  // custom code
  //but this line causes a runtime error

Because you placed the preventDefault() invocation at the top of the function, you have shut down the default behavior of the element. In other words, even though you get a runtime error, you haven't screwed up your form button, and the form doesn't submit.

The meaning of file permissions

Linux file permissions appear to be cryptic, but they're straight forward. "775" has an immediately intuitive meaning, if you are aware of two things:

1. Each number represents the permission for the file owner, for the group owner, and for everyone else.

2. The number represents the permission for that owner.

The permission number is arrived at by assigning a numeric value to each allowed permission:

= read (r)
2 = write (w)
1 = execute (x)
0 = no permission (-)

In the case of a file with permission 751, it can be deciphered to mean:

The owner of the file has permission 7, which is read (4) + write (2) + execute (1).

The group owner has permission 5, which is read (4) + execute (1).

Everyone else has permission 1, which is execute (1);

What is a javascript prototype?

What is a prototype in javascript?

A prototype is an object. Every object in javascript has it as a property. It can be considered the template for that object, and any other objects will use it to  inherit properties.

When you want to dynamically add properties or methods to a javascript 'class', you will use the prototype:

function bank(balance)
   this.balance = new_balance;
   this.getBalance = function(){ return this.balance; }

bank.prototype.deposit = function(amount){ this.balance += amount; }

var my_account = new bank(0);
alert("New balance is " + my_account.getBalance(); }

So the object prototype is found in object.prototype?

Uh, no. Although you will use object.prototype to modify the object's prototype, it isn't technically found there. If you want to access the actual prototype object, you need to look elsewhere. The object.prototype property is the prototype that is assigned to all instances of the object,

The true prototype of an object is held in the internal [[Prototype]] property. ECMA 5 introduced a standard accessor Object.getPrototypeOf(object) which works in Firefox, Safari, Chrome and IE9. All browsers (except IE -- surprise!) support the non-standard accessor __proto__. Finally, we can reach it through the object’s constructor via the prototype property.

var a = {};

//Fails in Opera or IE<=8
var myPrototype = Object.getPrototypeOf(a); //returns [object Object]

//Fails in IE
var myPrototype = a.__proto__; //returns [object Object]

// works all browsers
//(but only if constructor.prototype has not been replaced and fails with Object.create)
var myPrototype = a.constructor.prototype; //returns [object Object]

Can any object be a prototype?

Hell, yes.

The $64,000 question: so what?

The prototype is the seed for all other objects.  It's a way to dynamically change the internals of any javascript 'class'. When you update the prototype, any previously instantiated objects gain the update.

var dog = { }

var my_dog = new dog();
alert(; // undefined = 'sparky';
alert(; //'sparky';

dog.prototype.setName = function(name){ = name; }
dog.prototyp.getName = function(){ return; }

alert(my_dog.getName()): // 'fido';

My feelings about the code debate

A graphical representation about how I feel about the ongoing argument about the iPhone vs Android, or Windows vs Mac, or PHP vs Python et al

funny graphs - Apathy Charted

Why I like Starbucks

I like going to Starbucks in the morning for three reasons:

1. They have reasonably priced coffee,
2. They give me wifi and a place to hack in peace,
3. They pack their counter with loads of impulse buy items.

That third one is important: at 6AM, the last thing I want to do is make eye contact with anyone, much less one of their employees. The stacks of CDs, coffee packets, and nuts give me something to look at instead of them.

So I will buy your CDs, if only to avoid the small talk.

How to create an alias in Linux

How to create an alias

What is an alias?
An alias is a command typed on your terminal command line which immediately runs a macro of shell commands.

Where do I add my alias?
In your .bash_alias file, which is located in your home directory. To see a list of all hidden files, type ls -a.

How do I create an alias?
1. In the .bash_alias file, type "alias='<enter your command here>'
2. Save the file
3. Type in source .bashrc to reload your .bashrc file (which adds the aliases to your environment)

The reason I left one development job

A few years back at a place I worked:, the CEO said, "I never hire anyone over 40"

He looked at me with his early 30-something wisdom and reasoned. "They just don't get it."

"You just unhired me," I told him. "Well, you're different," He said. "I know it's not a good rule. But I still try and follow it."

The thing is, he's not that different from anyone else. He just has the insight to acknowledge that he was blowing smoke out of his ass.

We all make arbitrary rules that we follow, even ones we openly admit are based on fairy tales. In this specific case, his rule was just as arbitrary as any other. It was just also really stupid.

But developers do this kind of thing without giving it a second thought. How many of us are staunch advocates of camelCase or putting brackets on their own line? How many of us refuse to use one or another framework because "it's lame"? How many of us refactor because it "eliminates duplicate code", regardless of whether or not it makes the application less readable and maintainable?

It's human nature. We have to do it. It's how we get through the day. If we didn't we would have to come up with some semblance of a reason why we do the million little things we do. We would be so busy trying to rationalise why, that we would never end up doing it in the first place.

Things coders do to appear inscrutable

We all have them: self-appointed guardians of the code base. They will rigorously go over your classes with an eagle eye. They will find the suspicious code and point it out. But they won't fix it. Here are some of the things they do that make you want to drive an ice pick into their monitor.

They yodafy their conditionals

If you've ever come across a conditional like the following,

if (3 == $flag_value){

 then you've run across a yodagrammer and it is now your duty to find this person and slay them with a light saber. The only people who write code like this are the same people who carry on conversations in kermit-esque voices, saying things like, "Eat that muffin, you must," and then look at you like they think that you think  that they are the wittiest person since Groucho Marx hung a duck from a ceiling.

They Egyptifikill

You will hear their clarion call: "Everyone knows that brackets should be on their own lines. It makes it easier to read!"

If they come across:
if ( ... something ... ){

They will change it to

if ( ... something ... )

and then they will let you know that they had a hell of a time getting through the code because the crazy brackets were so damned confusing. The best way to deal with these people is to agree with them wholeheartedly. Every time you come across one of their changes

if ( ... something ... )

Change it to

        ... something ... 

They point out 'bad' programming in comments

Whenever they come across questionable coding, they make sure everyone knows that they have come across questionable coding with indignant comments. But here's the kicker: they don't change it.

    * OMIGOD please please PLEASE 
    * don't write code like this
    * magic numbers are HORRIBLE
    * and only sucktarts write code
    * like this
   if ( $some_condition == 1 )

They go crazy on indented embedded calls

Seeing a string of chained method calls drives them to reformat the code. In fact, they will spend an hour going over the code base to 'clean up' the code. This:

  $x = $this->getVal()->formatVal()->upendVal( $first_param, $second_param);


  $x = $this->getVal()

In theory, this makes it more readable. In reality, there is no actual evidence of this. Rather this is just inscrutable gospel. In true reality, it makes it even less readable because the person that has rewritten this has his IDE set up with screwy tab values, and it renders like this to everyone else:
  $x = $this->getVal()

How to commit a file permission change in svn

After constantly losing my permissions on a file with every update and commit, I finally had to do some research to figure out how to get the new permissions committed to svn. It turned out to be quite simple:

# svn propset svn:executable path/to/my/script/my_script.cgi
# svn commit

For more:

Don't find x, don't solve for y, and don't approach infinity

Dear Math, 
Stop asking us to find your X. She's not coming back, and you need to move on. Why not ask Z out for coffee?

Dear Algebra,
I will no longer solve for Y. Why is it that I am the one who is always supposed to pick up pieces of Y's disasters? Let Y solve his own damned problems.

Dear Calculus,
Thank you, no. I will not take a second derivative. The first one filled my up quit nicely.

Dear Math,
Stop trying to normalize the matrix. Has it ever occurred to you that the matrix might like who he is, and doesn't want to be normalized?

Dear Riemann,
No, you let n approach infinity. Infinity is an arrogant bastard, and I will not be part of this introduction.

Dear Division,
You want me to find you another common denominator? What did you do with the last ones I found you?

Using jquery to find a selected option in a drop down list

If you have a drop down list in your HTML form, automatically setting the index isn't a slam dunk. jQuery doesn't make it intuitive.

How to test if an option has been selected:

Option #1 - assign an id to the options in your select input. This makes it easier to compare the selected index with your target option.

if ($("#my_select option:selected").attr("id") == "id_of_the_desired_option")

// or

if ($("#id_of_the_desired_option").attr("selected") == "selected")

Option #2 - look at the specific value of the selected option. I don't like this because now you are hardcoding values into the code, and values can change easily, breaking your code. But it's an option, nonetheless.

if ($("#my_select option:selected").val() == "this is the option value")

Symfony forms - setting an empty value for an entity

It appears there is a bit of a bug in Symfony2, although it may have been patched with the more recent versions.

If you have created a formtype and one of your inputs is an entity, you may wish to have the first element in the drop down list to be empty (null).

To do this, you just specify 'empty_value' as a parameter when adding the input to the builder:

        'class' => 'Me\MyBundle\Entity\Person',
        'empty_value' => 'Please choose a person'

If you do this, then the first option will have a null value, and a label 'Please choose a person'.

This works great. However, the current symfony2 documentation says that this null option appears automatically if the input is NOT mandatory. In order to disable this first empty option, you have to turn off the empty_value parameter by doing this:

        'class' => 'Me\MyBundle\Entity\Person',
        'empty_value' => false

But this doesn't work. If you do this, you will get an error message:

Notice: Undefined variable: emptyValue in /home/one45dev/workspace/platform/vendor/symfony/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php line 85 

In fact, if you want to disable the first empty option, you have to set empty_value to null , not false:

        'class' => 'Me\MyBundle\Entity\Person',
        'empty_value' => null

Legacy code. Bill Gates would have been proud

Our site is going through a port to Symfony2 from an  patchwork of in-house framework attempts. Every now and then, we stumble across land mines as we are refactoring. Like this one.

     * probably returns this object's primary key in the db
     * @return int
     * @todo What the hell? PROBABLY returns it?
    public function getId()
        return $this->id;

Best programming tweets of the week

Apple's next move - the iBod:

I have no idea what to make of this:

Truer words:

Wait, these are actually truer words:

How do I find my version of apache?

It's simple to find the version of apache on a linux box.

$ httpd -v
Server version: Apache/2.2.17 (Unix)
Server built:   Oct 27 2010 10:04

Why isn't the IE emulation meta tag working? Cause IE is freaky

A heads up to anyone that is working with compliance issues on their web pages. If you want to force IE browser compliance, you can do it using a meta tag, but you MUST be careful of its placement in the HEAD tag.

The tag <meta http-equiv="X-UA-Compatible" content="IE=Emulate7" >

has to be the very first meta tag, otherwise it’s not guaranteed that the IE browser will fall into the IE7 compliance mode.

<!-- THIS IS GOOD -->
   <title>One 45</title>
   <meta http-equiv="X-UA-Compatible" content="IE=Emulate7" >
   <meta name="description" content="Stuff" />

<!-- THIS IS NOT -->
   <title>One 45</title>
   <meta name="description" content="Stuff" />
   <meta http-equiv="X-UA-Compatible" content="IE=Emulate7" >

Don’t ask why. Just accept IE for what it is and move on with your life, citizens.

Some references:

How to give sudo privileges

First, you must be logged in as root. Then, open up the sudoers file (I use nano because I'm lazy. vi is the editor of choice of people that prefer overkill when adding a single line of text):

# nano /etc/sudoers

Here's an example of a simple /etc/sudoers file that will give "justin" access to all root commands.

# User privilege specification
root ALL=(ALL) ALL
justin ALL=(ALL) ALL

That's sudo access in its entirety. For more detailed instruction, try

How to move records between mysql databases

Moving a db record from on database to the same table in another database is simple:

REPLACE INTO new_database.tableName SELECT * FROM old_database.tableName

If you need to get a bit more complex and extract only certain records from one table and move them to another database:

REPLACE INTO new_database.tableName
SELECT * FROM old_database.tableName WHERE id in (1,33,223,555 ...)

Or, you can do a subselect, to get child records from a foreign key

REPLACE INTO new_database.tableName
SELECT * FROM old_database.tableName WHERE your_foreign_key_column in (1,33,223,555 ...)

One level deeper

REPLACE INTO new_database.tableName
SELECT * FROM old_database.tableName WHERE your_foreign_key_column in
(SELECT id FROM old_database.foreign_tableName WHERE id=222)

There's important, and then there's Important

At our dev meeting last week, we decided to talk about the goals for Q2. Yes, it's already Q2 and yes, you generally have your quarterly goals set out before you actually start on the quarter. But code happens, and late goals are better than no goals at all.

We started brainstorming specific goals for the quarter. There were the usual suspects: refactor the ageing DAO layer, maybe replace the error handler that catches exceptions, then throws them into a black hole without any further reporting, and a team building exercise to San Francisco.

There were also a couple a touchy-feely issues: perhaps we should develop a development team mission statement that clearly identifies who we are, how we code, and why we code. Perhaps we should document the sprawling database, and the actually get the meaning of the more obscure column names (the meaning p_has_itern_pparker just isn't jumping out at us).

After we brainstormed a list, we divided them into the four quadrants made so famous by the book The Seven Habits of Highly Effective People (None Of Which Are In This Room Apparently). Each goal was either in the first quadrant (Important and Urgent), the second quadrant (Important, Not Urgent), the third quadrant (Urgent, Not Important) or the fourth quadrant (Not Urgent of Important).

As it turns out, every single task related to improving code, fixing bugs was considered either Important and Urgent, or just Important. Everything else was considered Unimportant.

I think this is the biggest trap development teams fall into. If it isn't a measurable improvement to the code base, then it isn't as important. That's why so few development teams have anything more than just an organized task management system.

This is why Red Mine is so popular these days. It excels at managing tasks, and, even more important, excels at managing busywork.  Exhibit A: the wiki. I have yet to find a Red Mine wiki that wasn't built like a slum in Rio. Navigating a Red Mine wiki is a lot like trying to trace the Amazon back to its source. Some links take you down rabbit holes. Some links take you to a suddenly unexpected table of contents. The only thing Red Mine seems to guarantee is that it will capture your information forever, and hide it from everyone else, lest they try to actually understand it or, worse, fix it.

How many dev teams have organised architectural documents? Few. How many have several dozen incomplete pages, littered with printouts of sql statements, and half-finished tables describing what the columns do? A few more. How many have nothing? The rest.

How many dev teams have mission statements, or at least a organised -- there's that word again -- statement of why the dev team adheres to a set of common principles? Practically none. Is it necessary? Of course. You may be able to function with it, but you're highly unlikely to function at an elite level without it.

If the only thing important is reducing the bug count, improving the code execution, and completing your tasks, the dev team is nothing that an artificially intelligent code writing routing (patent pending) couldn't do. Thank god we don't have artificially intelligent code writing systems. But we do have overseas developers, and they work for a third of what you cost. You better be three times as productive if your only a code monkey.

In the end, it was decided that the number one priority of the team, for the entire quarter, was to reduct the time it takes to enter a ticket in Red Mine, and move the status from New all the way through to Complete. So there you have it. We have our priorities in complete order.

Wrap all your sensitive computer equipment in bubble wrap!

Solar activity is expected to peak around 2013, and many scientists are warning that we could be in for a hell of a time. Most solar flares cause minor or no problems with satellites and power grids. But a major storm could be disastrous.

Like the Carrington Event.

Back in 1859, there were no satellites or delicate chip technologies to wring their hands in angst about. So what could a solar storm do? On September 1, as viewed and reported by Richard Carrington, it did a lot more than you might think.  Telegraph offices across the world got whacked by the flare. Some telegraph operators even reported electric shocks and, in multiple cases, claim paper caught fire.

Now the NRC says that a similar solar storm could cause up to $2 trillion dollars in damage. In a best case scenario. Some scientists are giving better than even odds that a Carrington Event type of storm is going to occur. If it does, you better hope you're wearing rubber soles. And stay away from telegraph offices.

Twig template: find the length of an array

It's not immediately apparent in the documentation for Twig, but finding the size of an array in a twig template is simple:

{% if my_list|length > 10 %}
{% endif %}

Or, you can extract the size into a variable:

{% set size = my_list | length %}


demotivational posters - IF YOU SEE DOTS

Is Google preparing for the future by profiling you now?

This just in from the Desk of the Minister In Charge of Conspiracy Theories: there may be a more sinister reason why Google wants to force us to use our real names: advertisers. We all understand what a gold mine a social network is for distilling trends and statistics, usage habits, likes and dislikes.

We all understand how marketers drool at the thought of getting access to this data. But how much will they pay if Google can actually tie usage statistics directly to named people? Think about it: suppose I am a mass marketer. I can buy a database of names and addresses and take my chances with a mass mailout.

But what if I could buy usage data from Google, complete with names of individuals, and then cross reference it with the addresses I now have on file? Suddenly, I have a database of pinpoint data. I know their likes and dislikes. I know their habits. I know what they've been doing these past few months. And I have their phone number and address.

The good news is that this is just a far fetched conspiracy theory. Google's privacy policies imply that they will not do this. However, there is a hot debate about the concept of online privacy. A year from now, two years from now, five years from now, the idea of online privacy may completely change. It may be considered normal to share your online activities. It may be considered an acceptable practice to profile users, and then allow marketers access to these profiles. If so, Google is well positioned to provide the most accurate user data available on the web.

 None of it is happening now, as far as any of us know. But the world changes on a dime. There appears to be a long term method to this short term madness.

Writing PHPexcel to a buffer

The standard way to export an excel spreadsheet with PHPExcel is to have it written to disk, then extract that data using file_get_content(). But I am using symfony and wanted to be able to pass it around from a widget to a controller that would send it out with the appropriate headers. I didn't want to write to disk because it was a high volume application that would result in a lot of disk writes, and possible race conditions, if done poorly. Which is how I typically do things.

Not sure how to do it, I put a question up on stack overflow. I only got one answer, but it was the right answer, and I'm able to make PHPExcel write the contents of an excel file directly into a variable:

$writer = PHPExcel_IOFactory::createWriter($phpExcelObj, 'Excel2007');
   $excelOutput = ob_get_clean();

However, the guy that replied also made a snooty remark about how I was perhaps an idiot for not writing to disk first. I wrote a response saying that, while I appreciated his insights into my intellect, my question was how to do something, not his by-the-gospel opinion on whether or not I should follow the PHPExcel playbook.

Just before sending it, however, I started to wonder why he would say something like that, and whether or not he was just some crank trolling StackOverflow, so I checked out his profile.

Turns out he's one of the actual authors of PHPExcel. And rather well respected. I have 49 reputation points on Stack Overflow. He has 36,000. His opinion carries a bit more weight, I should think.

I sent him a note thanking him for his input, and then I voted him up.

This morning's email

TO: All Employees


Everyone, I won't be in to work today. Last night I tried to drown my sorrows, but my sorrows were stronger than I expected, and fought back and oh god it was horrible just horrible.


When I was a kid my dad took in a novel

A recent survey found that 35% of tablet owners use the device while they're sitting on the toilet. The same people also take their tablets to restaurants (30%), on vacation (60%) and in bed (78%).

Ironically, 80% also said they see tablets as a means to help them achieve an improved work/life balance: 40% use it to stay connected with friends. Hopefully not while they're sitting on the john.

 The survey was done by Staples, and I'm not surprised at the results. Based solely on the statistics at hand, I can say with authority that the majority or respondents were married with children. The bathroom is the only place you can get any respite from the kids. And, being married with kids, there's not a lot happening in the bedroom any more, so why not take your tablet to bed?

How to reset a mysql primary key

Sometimes you want to reset your auto_increment primary key in mysql so that the newly inserted records start at 1. In my testing database, for convenience, I want to do this (never mind why. Just live with it. Any smug comments about depending on fixed primary key values are noted, so no need to add them. Unless you're a dick).

Resetting the primary key is straightforward:

alter table foo AUTO_INCREMENT = 1

How to kill a linux process

The Kill command does exactly what it sounds like: it kills a process. It sends a signal to a process to kill itself. Here are three ways to kill a linux process:

Step one: find the process

Suppose you wanted to kill a certain httpd process. First, you need to find it:

# ps -ef | grep firefox
2073 ?        Sl     1:07 /usr/lib/firefox-3.5.3/firefox

There are other ways to effectively kill a process — killing a process by name, killing a process by specifying part of the name, killing a process by pointing out the process with cursor etc.,

In this article, let us review 4 ways to kill a process.

1. Kill Command – Kill the process by specifying its PID

All the below kill conventions will send the TERM signal to the specified process. For the signals, either the signal name or signal number can be used. You need to lookup the pid for the process and give it as an argument to kill.

$ kill -TERM pid

$ kill -SIGTERM pid

$ kill -15 pid
Example: Kill the firefox process.

$ ps -ef | grep firefox
2073 ? Sl 1:07 /usr/lib/firefox-3.5.3/firefox

$ kill -9 1986
2. Killall Command – Kill processes by name

Instead of specifying a process by its PID, you can specify the name of the process. If more than one process runs with that name, all of them will be killed.
Example: Kill all the firefox processes

$ killall -9 firefox
3. Pkill Command – Send signal to the process based on its name

You can send signal to any process by specifying the full name or partial name. So there is no need for you to find out the PID of the process to send the signal.

Example: Send SIGTERM to all the process which has sample in its name.

$ pkill sample

How to debug your ssl certificate installation

If you're, like me, a hack who is always treading treacherous waters, who knows just enough server administration to destroy his own server, but so proud - or cheap - that you insist on doing it all yourself, you will eventually install a SSL certificate.

And you will eventually screw it up. I don't know why you did. I'm not sure how to fix it either. But, having screwed up enough times on my own, I know a few tricks that will solve most of the problems you have.

Hard and fast rules:
  1. You are going to screw it up. Maybe you won't. Maybe you're going to meticulously follow the steps, checking your list twice like Santa. Congratulations. You are the 1%. For the other 99%, assume you're going to do something wrong, and move forward with that expectation.
  2. Back up everything, everything, everything. Can you imagine the hell you will go through if you edit an apache conf file so hard that it bleeds, then breaks, and you have no record of what you changed? For god's sake, man, you aren't Linus Torvalds (which is actually a very good thing, because he's dead). 
  3. Get your instructions in place. Your SSL issue will have them for you and, if you follow them slowly enough, you will probably have no trouble. But you won't, will you? Of course not. You're a server administrator and those instructions were meant for morons.
So now follow the installation steps, restart apache, then sit back annnnnd ...

...stare at the error screen on your browser. And then panic when all seven of your private blogs, spam sites, and failed startup attempts are now down because apache won't restart. 

What do you do? Here are some of the things I have done to eventually get me back on track:
  1. Phone my systems admin friend and have him tell you what to do. But I guess that's not a practical approach. I don't want to spend too much time handing out his phone number. And he might get mad.
  2. Is the SSL engine turned on? Of course it is. Why would I ask such a stupid question. I myself have never accidentally missed a configuration setting. And for that matter, there's no reason to check if you have told apache to listen on port 443, is there?
  3. Type in
    # sudo apachectl configtest
    . Of course you ran this test before you restarted the server. Of course you didn't forget this one time. Just get over it and run configtest, and it will spit back any errors are you.
  4. Turn on debugs in your conf file: LogLevel debug.
  5. Compare your key and certificate. If they don't match up, you have installed wrong, and should just start again from scratch. The private key contains a series of numbers; two of those numbers make the "public key", and the others are part of the "private key". The "public key" bits are also found in your Certificate . Check that the public key in your cert matches the public portion of your private key:
    $ openssl x509 -noout -text -in server.crt
    $ openssl rsa -noout -text -in server.key

    Also try:
    $ openssl x509 -noout -modulus -in server.crt | openssl md5
    $ openssl rsa -noout -modulus -in server.key | openssl md5 

Uh, wait, what?

Some thoughts are better left unformed. Some insights are better left unsighted. Somewhere a nerd has earned his wings.