Category: Programming
Read your diffs
Please, please, read your diffs before sending code for review.
bind
There are those times I come across an article that are so amazing simple and obvious that it immediately changes the way I write code. Understanding JavaScript’s Function.prototype.bind is one such article. It’s one of those articles that talks about something I always knew, but never really thought about it that way before.
I’ll let the article speak for itself, but I want to give you the pattern I enjoy now. I want to show you how it makes itself easy to approach and use.
So, let’s say we have this bit of code.
Buckets.prototype.add = function(data)
{
var stopEarly = ! (this.options.stop_on_match === true);
_.each(this.bucketConditions, function(c){
if(c.test(data)){
this.buckets[c.name].push(data);
return stopEarly;
}
}.bind(this));
return this;
};
This is part of a buckets node package I’m finishing up. Now, I want ‘data’ to be whatever they pass in, so this could be an object, an array, or whatever. Because of that, however, I need to create another function that allows the user to enter in a list of data.
Buckets.prototype.addList = function(data, cb) {...};
Obviously, I want to reuse the ‘add’ function already created. So I add this:
Buckets.prototype.addList = function(data, cb)
{
var that = this;
async.each(data, function(v){
that.add(v);
});
};
We’ve all seen code like that. However, the article mentioned above reminds you about .bind, and its special ability to bind the function to a certain object as context. This means instead of writing the above code, I can do this:
Buckets.prototype.addList = function(data, cb)
{
async.each(data, this.add.bind(this), cb);
};
This is so much easier, and so much more elegant. I highly suggest reading the above article. It’s wonderful.
How We Killed Our Process, Technology Stack, and Assumptions — and Survived
Atlassian Summit 2013 Talk
Inbred Code Review
I’ve never heard this term before, but it’s something I’ve coined here at work. Essentially, it’s when a few people working on the same project pass code reviews back and forth to one another. Problems in the code are harder to detect, because the same group of people get tunnel vision. They see the same code all day long, and find it harder to edit.
Code reviews are supposed to solve that problem. You giving your code to another person to review, to pass a critical eye looking for design mistakes. When the people you pass your code to is as familiar with the code as you are, it deadens their ability to look at your code with a fresh look.
Be wary of inbred code reviews. Try to include on person not familiar with the project on code reviews.
“Jason, looks ok to me, but I think we need to expand the gene pool on this baby.”
On another note, I didn’t realize it was so long since I last blogged. I have a lot to write, so I’m going to try to implement some form of schedule for writing more often. I enjoy it, I just forget to.
PHP Tips and Tricks: Array Lengths
This is a simple trick. It makes the assumption that you manage your arrays properly, and in this case, you are using an array (or list), and not a dictionary. Basically, a list that starts at 0 (though, the method can be adjust to fit other starting points).
Anyways, there are times I need to know if an array contains 15 elements. I can quickly discover this like so:
if ( isset($array[14]) ) {
All this does is check to see if there is a value set for element 14. Again, this makes the assumption that the interface you are calling returns what it says it will. It should, and if it doesn’t, that’s a serious bug.
This also comes in handy if I only want to return a subset of the information, and need to find out if there is more information. Let’s say I want to return as little information as possible via the API (I only want to return the first page of results), but I also want to know if there are more results (for pagination, let’s say). I can then ask the API for 16 results, and then check if there are more results like so:
$isMore = isset($array[15]);
With this simple technique, I need only return 16 results. I don’t need to do anything else fancy, just return 16 results, display 15 of them, and recognize that there are more results.
Finally, you can use this technique to ensure the length of a string. So, lets say we want to enforce a minimum line length for passwords, we can enforce it like so.
$isPasswordLongEnough = isset($password[7]);
Obviously in all these cases, we have to be aware of off-by-one errors. For example, $password[7] checks for a password of at least 8 characters, not 7.
Injectors: Dependency Injection with Traits
With the release of PHP 5.4, Traits were added to our toolbox. And, if I might be so bold, it’s one of the most exciting features I’ve seen come out of PHP in a long time.
Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.
A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.
With this in mind, I knew when I first saw traits that it was the way to solve dependency injection. Granted, when I say solve dependency injection, I’m mostly referring to the way dependency injection (or DI) is being solved in the current incarnations of PHP frameworks. Basically, through the use of dependency injection containers (DIC). Essentially, a dependency injection container stores objects, or the ability to create objects, in some “master” object or container. I’m not going to spend too much time on what DI is, or what a DIC is. Fabien Potencier has done an excellent job on the subject with is “What is Dependency Injection” series.
Anyways, let’s be clear about two things here:
- Dependency injection is good.
- Dependency injection containers solve a real problem.
However, the current incarnations of DICs have problems of their own. First, let’s cover a problem with basic DI, and what DIC solves.
<?php class User { protected $record; public function __construct( $userId ) { $db = new DB( ); $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( ); } // .... } $user = new User( 1 );
So, you might recognize this style of programming. A User is created by passing a $userId to the constructor, whereby it calls the DB class to fetch a record. What we’ve done here is couple the User class to the DB class. This means we can’t ever create a User unless we have a DB available. If we want to create a User from some other source, we can’t without a rewrite. It also makes testing User difficult. To test User, we also need to use DB, and make sure that is setup.
The first step to a solution is to inject the DB into the User class like so.
<?php class User { protected $record; public function __construct( $userId, DB $db ) { $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( ); } // .... } $user = new User( 1, new DB( ) );
Now, when we create the User class, we need to pass in the DB container. That way, we can “inject” into the User class any data store we want. In fact, we’d probably want to take this a a step further and instead of requiring a DB class, we wants to require an Interface of the DataStore type.
<?php interface DataStore { public function get( $source, $condition ); public function limit( $limit ); public function execute( ); } class DB implements DataStore { // implementation goes here } class User { protected $record; public function __construct( $userId, DataStore $db ) { $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( ); } // .... } $user = new User( '1', new DB( ) );
Okay, so here we see the DataStore hsa been quickly drafted (it’s actually a fairly bad implementation, but serves for the examples).
This means if at some point, we want to create a User from some call to an API, can can inject that instead.
<?php interface DataStore { public function get( $source, $condition ); public function limit( $limit ); public function execute( ); } class DB implements DataStore { // implementation goes here } class API implements DataStore { // implementation goes here } class User { protected $record; public function __construct( $userId, DataStore $db ) { $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( ); } // .... } $user = new User( 1, new API( ) );
And that is dependency injection. However, a problem occurs a your class starts needing more and more.
<?php class User { protected $record; public function __construct( $userId, DataStore $db, ISession $session, IConfig $config, ITracker $tracker, IMailer $mailer) { $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( ); $session->start( $this->record->userid ); $session->lifetime( $config->yes ); // ... } // .... }
Suddenly, you keep adding more and more to your constructor, and it takes on a whole new meaning. Even worse off is that you might not need the Mailer unless you want to send the user a message. This means unless you are sending a message, you are creating an object that won’t ever get used. This also places a lot of work on the programmer using the User class. Every time they want want to create a User object, they need to create all these classes. Sure, you could only require the Mailer if the user is going to message someone, and require they use a setMailer( ) function, but that creates even more confusing.
Yeah, gets fairly confusing fast.
So, what do we do about that?
Dependency Injection Container
The idea with the DIC is that you can store your objects, or the generation of those objects in one central registry (generally an array) that can be called from anywhere. In our example, it might look like this.
<?php class User { protected $record; public function __construct( $userId ) { $db = Container::get('DB'); $session = Container::get('Session', array('userId' => $userId)); // ... } } new User( $id );
In this case, Container is simply that, a container of other objects. We map the string ‘DB’ to a method, or some system that will return to us the DB class. Actually, that’s not quite right. Instead, it returns, in our example, a class that implements the DataStore interface.
In our Container, we can make what DB returns actually be anything we want.
This helps tremendously in testing, because we can setup DB to be something other than an actual DB class. It can simply be a mock DataStore object setup just for testing.
This is where we currently stand with dependency injection containers in PHP. They are, for better or worse, global arrays we pass around. That isn’t so much a problem. Rather, the problem is one of discovery. Remember how I said containers like this map a string to an object? That’s because that’s pretty much all it does.
I pass in DB, and I hope I get back an object like DB. But where do I go to find out what exactly is happening? Container::get isn’t actually generating the object. That’s most likely abstracted out someplace else. Another problem is knowing which values get will accept. If I call Container::get(‘Cookie’), will that work as expected? What about Container::get(‘Mailer’)? What do these actually return? Nothing enforces this, nothing is easily discoverable through straight PHP code. And, frankly, I don’t know how you’d document this.
Container::get, at best, can tell you to pass it a string, and it will return, maybe, something.
It basically comes down to this:
$user = new GoogleTracker( );
// versus
$user = Container::get(‘Tracker’);
In one case, you know exactly which object you are going to use. In the other, you can only assume. In the former, you can get to the code quickly. In the latter, you cannot.
Don’t get me wrong, DI and a DIC solves a problem. It’s just missing a crucial piece to complete it.
Traits to the Rescue
So now we come to traits. Let’s start with a simple example. In most applications, their exists a concept of configuration.
namespace Lib; class Config { protected $loadedConfigFile = null; protected $configName; /** * @param string $configFile Full path to config file */ public function __construct( $configFile ) { $this->configName = $configName; } /** * @return object */ public function getConfig( ) { if ( ! isset($this->loadedConfigFile) ) { $this->loadFile(); } return $this->loadedConfigFile; } /** * Loads the config file * * @return void */ protected function loadFile( ) { $this->loadedConfigFile = json_decode(file_get_contents($this->configName)); } }
Ignore the lack of error checking (please!), and let’s explore how we could use a trait to load this. What we want is to enforce that the same config file is only loaded once. That way, multiple calls to create Config will only ever have to load the file once. So, our trait would look like this.
namespace LibInjector; trait Config { /** * @return LibConfig */ public function getConfig( $configName ) { $keyName = __TRAIT__ . $configName; if ( ! LibContainer::exists( $keyName ) ) { LibContainer::set( $keyName, new LibConfig($configName) ); } return LibContainer::get( $keyName ); } }
Here, the Config trait is created. We’ve contained the loading code for a Config object in a single place, and that place is easily discovered. Now, when we want to use the Config class, we can add it to a class like so.
You’ll note I placed the Config trait into the Injector namespace. I like to think of traits used in this manner as an injector – the trait allows you the program to easily inject other needed code into your code.
namespace Lib; class User { use InjectorConfig; function __construct() { $this->config = $this->getConfig( 'UserConfig.json' ); } }
But does this really abstract out the calling of the code? Sure!
In this case, the trait Config’s getConfig method is fairly short, but that doesn’t mean it can’t expand to handle other cases. If you want to replace LibConfig with AnotherLibConfig, it’s simply a matter of switching it out. You can also have getConfig use both Config libraries, determining which one to use based not the $configName passed (let’s say, to handle an XML config file, and a JSON config file, and using two different libraries to handle that).
Injectors are also testable. Granted, you’ll have to Mock out the test Injectors, but I found that to be easy as well. Again, you can do anything you like in the injector, so handling different test cases is trivial.
Using injectors also give you the benefit of an easy code path to follow. After all, the class is explicitly using InjectorConfig, which is a specific trait, and easily discovered. Most IDE’s will make this as easy as clicking on the name Config and it will take you right to the appropriate trait. And there you see the creation code.
Also, you’ll note getConfig has been given the tag @return LibConfig. This again provides for clear documentation, and IDE’s should return the proper type, allowing for better auto completion.
I’ve yet to find a case where using an injector has made things difficult or challenging. And it’s wonderful to work with them. If I’m in an object and need to include a Config or Cache object, it’s as simple as adding a use statement at the top of the class and it’s available.
Injectors
I hope you find the use of Injectors interesting. If you have any questions, let me know. I’ll try to answer them. This article has been sitting in my drafts file for far too long, and I need to get it out. So, I’m sure there are errors riddled throughout. My apologies. However, I hope the message gets across. Try using Injectors, and let me know how they work out for you. I’d love to hear it.
vim faster with maps
At myYearbook, we pack our JS and CSS files. Much of this is automated now with Jenkins, but we still have legacy code that must be packed by hand. And, at the same time, it’s generally wise to test your product with a packed file regardless. I also try to make it a habit to phpcs my file as often as possible. The goal here is to keep the file as tidy as possible, and not waiting for the end to fix everything. Also, during the course of development, I might come across other little things I want to do, and I use vim to make things as easy as possible.
maps
I do this through maps. I map is fairly simple to setup in vim.
:map ,cs <ESC>:w|:!phpcs --standard=myYearbook %:p
Typing that into a vim instance means I can type ‘,cs’ in normal mode, and vim will w my file to disk, then run phpcs using the myYearbook standard on the current file I’m working in. Now, I use that often enough that I’ve added it to my .vimrc file.
map <Leader>cs <ESC>:w|:!phpcs --standard=myYearbook %:p
If you aren’t aware, <Leader> is set to ‘,’ using this bit of code in .vimrc:
let mapleader = ","
The comma is popular, but you can use whatever you want, really.
I can also pack my javascript and CSS files with similar ease using “,pj” and “,pc” (pack javascript, and pack css).
map <Leader>pj <ESC>:!jspack %:p > %:p:h/%:r:r.js map <Leader>pc <ESC>:!csspack %:p > %:p:h/%:r:r.css
You might be wondering what the ‘%:p’ part is. It’s actually part of the expand functionality of vim. Basically, the important parts here to understand is that the % is the current file name. The “:p” and “:r” parts are the modifiers. In this case, “%:p” has us expand to the full path. The “:h” modifier removes the last component. So, “%:p:h” basically says “Give us the full path, and then remove the head. The head in this case is the file name, so if the full path (“%:p”) is /Users/jasonlotito/test.php, “%:p:h” gives us “/Users/jasonlotito”.
“%:p:h/%:r:r.js” allows me to rename my file. In our setup, unpacked files contain the extension “.unpack.” By Simply using the “:r:r” modifiers, I strip off the “.js”, and then the “.unpack”, leaving me with just the file name. So, if my javascript file was named Modifiers.unpack.js, I’d be left with Modifiers. I prefix that with %:p:h/ which gives me the directory the file is in, and append “.css” to the path.
Being able to map commonly performed actions, especially to external tools, means I can stay in vim longer. Sure, I’ll still background vim when I need to perform certain actions, but I’m more apt to start scripting repeated actions, and then mapping them.
Someone thinks this is good
No. How this is considered good, I don’t know. Who wrote the code isn’t important – this is the way the code is supposed to be written. At least, this is the way it’s being demonstrated. With a straight face.
I cannot fathom how anyone can honestly think this is good and want to encourage its use.
<?php return array( // lots of config stuff here /** * Routes */ 'ZendMvcRouterRouteStack' => array( 'parameters' => array( 'routes' => array( 'zfcuser' => array( 'type' => 'Literal', 'priority' => 1000, 'options' => array( 'route' => '/user', 'defaults' => array( 'controller' => 'zfcuser', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( 'login' => array( 'type' => 'Literal', 'options' => array( 'route' => '/login', 'defaults' => array( 'controller' => 'zfcuser', 'action' => 'login', ), ), ), // more config stuff here );
Learning the vi language
I’m a long time user of vi (and I use vi interchangeably for both vi and vim), but it wasn’t until recently that I really started to understand the way vi works. Oh, I could be productive in vi, but I wasn’t adept at learning vi. I edit files in vi, I could open windows, I could move around, copy and paste, search and replace, and generally do the normal things you can do in other editors. So when I had to open up vi, I didn’t freeze up and get lost.
Don’t Repeat Yourself
The problem here is two-fold. First, I was looking for how to replicate actions I would perform in other editors. Saving a file, editing text, copy and paste, search and replace: all these things easily map to something you’d do in a traditional IDE. You don’t replace a character in a traditional IDE. You delete a character and enter a new one. To copy and paste big blocks of text, you highlight that text with a mouse. You navigate to different tabs with your mouse. When you want to split your window, you probably have to do so with the menu. You don’t append to a line. You simply move your cursor and start typing. You don’t jump to a character, and while you can, you rarely jump to a line. You aren’t yanking lines, you don’t concern yourself with buffers, and you don’t repeat your actions.
Basically, an IDE more closely resembles a word processor for programming languages, whereas vi is a completely different beast (vi vi vi, editor of the beast, after all).
Therefore, the first thing I had to understand before really learning vi was I had to look past replacing what I did with an IDE, but rather, understand how to do things in vi. And this is a fairly easy concept to understand once you learn one of the defining principles of using vi: if you have to keep pressing the same key to do something, you are probably doing it wrong. Consider the basic movement keys: hjkl. Using ‘j’ and ‘k’ to move more than one line should indicate to you there is a better way. Moving to the top of the screen, the bottom, the middle, move up a page, half a page, or down. These aren’t things you do in an IDE (you scroll), but in vi, that is an essential piece to the puzzle.
So, every time I wanted to do something, and I found myself repeating actions that seemed awkward, I’d search for a way to do it.
Find out more about noticing and unlearning vi anti-patterns with this excellent article from Tom Ryder.
Learn the Language
This leads us to the second thing I had to understand in order to really being learning vi. You don’t learn vi by learning commands, you learn vi by learning a language. Once you have a firm grasp of the language, you can start putting together your own commands. Discovering new commands seems to become more intuitive.
Lets see this language in action. Normally, if you want to delete a line, you’d type ‘dd’. This deletes the line (and stores it away so you can paste it later if you want). What if you want to delete more than one line? You could repeat ‘dd’ on each line you wanted deleted. But let’s say you want to delete the next 10 lines. This is where the language comes in. What you want is to delete 10 lines down. So, you start with ‘d’, then enter 10, and finally, ‘j’ for:
d10j
This isn’t so much a command you need to remember. Rather, it’s easier if you understand the language. Deleting 5 lines up can be constructed the same way:
d5k
Once we learn how this language works, we can create our own commands
‘==’ will indent the current line. We can follow the same pattern as delete to construct the following:
=5j
This properly indents the next 5 lines. Of course, we can also do ‘gg=G’, which will move you to the first line, and then indent all lines until the last line. We can do ‘ggdG’ as well, which will delete all the lines in the file.
The actual commands aren’t important. Rather, it’s the language. Once you understand how ‘d’ works, you can use the same language in other areas as well.
Want to copy the next five lines? Just knowing that ‘yy’ will copy the current line, you could easily discern that ‘y5k’ will yank (copy) 5 lines up.
You can learn about speaking the vi language by reading an excellent article from Yan Pritzker.
Investment of time
Yes, learning vi will take time. It’s not something that will come naturally. It’s a tool, and like any powerful tool, you have a lot to learn to truly start taking advantage of it. It’s a professionals tool. It’s a craftsman’s tool. It’s something that, regardless of whatever else you might learn, will benefit you as long as you are programming.
Sure, you might enjoy your IDE, and I’m not here to suggest you drop your favorite tools. Rather, it’s worth the investment to understand vi, it’s language, and how it works. Even if you aren’t using it every single day, you’ll appreciate being able to open up the editor and using it without feeling constrained.