Diablo 3

From killing the Butcher and filling rooms with Firewalls in the original to running thousands of Baal runs while competing on the ladder for Diablo 2 (LOD) … You would think that I would have tired of the series.  But here it is, nearly12 years since the last Diablo release and I have to say … I like what I’m seeing out of the new version.  Game play is similar to the beta so I knew what I was getting, but still … it’s a damn fun game.

Oh, and +1 to Blizzard for including a lot of the same old sounds!  I have to say, that always makes me smile.

Code Anaylsis: The Good, The Bad, & The Ugly

I’ve had the opportunity to work on a lot of different code in my days.  Different languages, originating developers, programming styles, and more …  but I have to say, I was somewhat surprised when I ran a code analysis tool across a bit of code today and saw the following:

The method setSomeMethod() has an NPath complexity of 1912680. The configured NPath complexity threshold is 200.

NPath complexity 1,912,680 … That has to be some sort of record.  Next time you’re writing PHP code for fun or profit take a moment to reflect on what your write.  Maybe run a tool (PHP Mess Detector for instance) and then really understand what it tells you about your code.  It might make you a better coder.

Note: NPath complexity of a method is the number of acyclic execution paths through that method. A threshold of 200 is generally considered the point where measures should be taken to reduce complexity.

Code formatting for a better tomorrow.

Spaces, tabs, curly braces, oh my!

Once upon a time there was a developer.  The developer loved to code and liked his co-workers.  However, this developer did not like the fact that his co-workers constantly ignored the coding style guide that the original team spent time to talk about and create.

What is a guy to do?  Well, the obvious solution was to remind them about the style guide posted on the wiki.  To make life easier, he also updated the style guide with a Subversion .XML formatting file.  This made it so that all his friendly co-workers have to do is hit Shift-Command-F (yes, they are a Mac house … we’ll talk about that in another entry) to format their code in order to be in compliance with the standard …

Forward to a check-in 3 weeks later … and nothings changed.  Tabs are still in place, lines run long, brackets are not on the correct line, and a half dozen other seemingly small formatting errors have crept back in.  What’s a guy to do?  Well an obvious choice on the PHP side of the house is to look at something like Code Sniffer.

Code Sniffer is a pear module that will sniff out PHP, Javascript, and CSS coding standard violations when passed in a coding standard and a file to process.

Coding standards?  Coding standards?  We don’t need no …

Before we talk more about Code Sniffer, I can already hear a few folks choking back the, “But why do we need standards?!” question … and it’s a good one.

As we learn a language and write more and more code, sometimes for one company, sometimes for many, we all start to develop our own specific brand of coding.  These coding style choices rarely affect small projects or projects with only a handful of people involved but once a project starts to become large or start to have a number of hands touching them the coding styles (or the jump between them) can actually impact the maintainability of a code base.

“Huh?  How does having my curly braces on one line vs. another effect maintainability.”, you say?  Adopting a standard allows developers to know exactly what to expect.  This increases readability of the code base and that results in faster debugging.  In addition, consistent standards allows for an “expected” look and feel across multiple IDEs.

Whats so spiffy about Code Sniffer?

Code Sniffer, as mentioned earlier, detects deviations of the chosen standard.  Even better, it can easily integrate with existing continuous integration systems or be used to generate reports to help coders see what issues exist and in some cases, who is causing them.

Setting up Code Sniffer

Code Sniffer is available as a pear package.  You can install it using the the older pear install method:

pear install PHP_CodeSniffer

Or use the new Pyrus (Pear2) install method:

php pyrus.phar install pear/PHP_CodeSniffer

 Using it for the first time

Once installed you can start using Code Sniffer right away.  While it does provide you the option of setting up your own specific style guide, you can use one of the included styles to see where you stand right away.  To see which styles are available, execute the following:

phpcs -i

That should return a list similar to the following:

The installed coding standards are MySource, PEAR, PHPCS, Squiz and Zend

You can test your install by selecting one of the pre-installed standards and building a report.  For this example, we will first set the default coding standard to test against using the following command:

phpcs --config-set default_standard Zend

If you do not have access (root) to change this, you can pass in the standard to use by passing along, `–standard=Zend` to phpcs.  Once the standard is set there are several different reporting options you can choose from.  To see a list of all options type:

phpcs -h

To start, lets run a summary report against a file (replace IndexController.php in the following example with a .php file of your choice):

phpcs --report=summary IndexController.php

PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE                                                            ERRORS  WARNINGS
--------------------------------------------------------------------------------
...Repos/trunk/www/application/controllers/IndexController.php  218     129
--------------------------------------------------------------------------------
A TOTAL OF 218 ERROR(S) AND 129 WARNING(S) WERE FOUND IN 1 FILE(S)
--------------------------------------------------------------------------------

Time: 1 second, Memory: 35.75Mb

As you can see from the example, the current IndexController falls well outside the Zend coding standard.  If we wanted to see who the major offenders are we can opt to run the `svnblame` report (this is assuming you use SVN as your source control system — there is also gitblame and hgblame for those using Git or Mercurial).

phpcs --report=svnblame IndexController.php

PHP CODE SNIFFER SVN BLAME SUMMARY
--------------------------------------------------------------------------------
AUTHOR                                              (Author %) (Overall %) COUNT
--------------------------------------------------------------------------------
jason                                                  (17.04)     (97.41)   338
howard                                                  (4.52)      (2.02)     7
nicoli                                                     (0)      (0.58)     2
--------------------------------------------------------------------------------
A TOTAL OF 347 SNIFF VIOLATION(S) WERE COMMITTED BY 3 AUTHOR(S)
--------------------------------------------------------------------------------

Knowing who to harp on is always fun but it doesn’t really help identify what the issue really are.  To get a more detailed report we need to run a `–report=full`.  That will display something like the following:

FILE: ...r/Documents/Repos/trunk/www/application/controllers/IndexController.php
--------------------------------------------------------------------------------
FOUND 218 ERROR(S) AND 129 WARNING(S) AFFECTING 325 LINE(S)
--------------------------------------------------------------------------------
   13 | ERROR   | Protected member variable "fb" must contain a leading
      |         | underscore
   14 | ERROR   | Protected member variable "user" must contain a leading
      |         | underscore
   15 | ERROR   | Protected member variable "auth" must contain a leading
      |         | underscore
   16 | ERROR   | Protected member variable "conf" must contain a leading
      |         | underscore
   17 | ERROR   | Protected member variable "adminConfig" must contain a
      |         | leading underscore
   18 | ERROR   | Protected member variable "frontController" must contain a
      |         | leading underscore

... chomp ...

 2011 | WARNING | Line exceeds 80 characters; contains 110 characters
 2012 | WARNING | Line exceeds 80 characters; contains 93 characters
 2015 | ERROR   | Expected "if (...) {\n"; found "if (...)\n            {\n"
 2017 | ERROR   | Expected "if (...) {\n"; found "if (...)\n
      |         | {\n"
 2020 | ERROR   | Expected "if (...) {\n"; found "if (...)\n
      |         | {\n"
--------------------------------------------------------------------------------

Time: 1 second, Memory: 35.75Mb

Alright, so now that we see the errors and warnings, what if we decide we don’t care about them?  Well, the best way to get rid of them is to create your own custom standard (something I won’t cover in this quick write up).  Alternatively, you can check out the standards that are being used for this check by changing the report type to `–report=source`.  After running that we’ll end up with a list of standards, errors, and frequencies for each standard non-compliance we ran into.

PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
STANDARD  CATEGORY            SNIFF                                        COUNT
--------------------------------------------------------------------------------
PEAR      Control structures  Control signature                            185
Generic   Files               Line length too long                         129
Generic   Files               Line length max exceeded                     18
Zend      Naming conventions  Valid variable name private no underscore    12
Zend      Naming conventions  Valid variable name not camel caps           3
--------------------------------------------------------------------------------
A TOTAL OF 347 SNIFF VIOLATION(S) WERE FOUND IN 5 SOURCE(S)
--------------------------------------------------------------------------------

Time: 1 second, Memory: 35.75Mb

Armed with that knowledge you can manually edit the offending standards or (even better) copy them into your new standard.  To learn more about creating a custom standard visit Creating coding standards for PHP CodeSniffer.

Conclusion

Some of the coding standards are very strict in relation to others.  For example PHPCS will generally find a lot more issues then the Zend standard will when you first run it.  If you are not going to make a custom standard, work with your fellow developers to select the standard that most fits the vision of your company while easily integrating with everyone’s current styles.  Don’t worry if a few people grumble about x or y, just deciding on a standard will help you get on the right path and who knows, eventually even the grumblers might start to realize how convenient a style guide and coding standards can be.