Monday, May 24, 2010

Rails has no place at the office

This is a milestone post for me! My first ever purposefully incendiary title!

I should probably run with it and try to get everybody super offended, to the point where you have no idea what my point is because all you can see is red. I guess I'll have to leave that for a future milestone...

Because, yeah, I'm not really serious. Rails has a place at the office. And no, this isn't going to be one of those "Is Rails ready for the Enterprise?" posts. Rails is perfectly ready for use in the Enterprise, but that's the wrong question.  As usual, the right question is much more complicated.

To start with, let me point out that this conversation has nothing to do with Ruby vs. C#. It doesn't really have anything to do with Rails vs ASP.NET MVC either. Instead I'm going to be talking about Active Record vs. Data Mapper, and View-Models vs. no View-Models, and this general concept of "the straight and narrow" vs. explicit abstraction and control. These are design patterns which apply to any language and appear in many different frameworks.

Rob Conery recently wrote a blog post in which he said,
For a lot of .NET/Java devs this will look "messy" - you shouldn't elevate "data concerns" into your model. This argument makes good sense for a large, complex site - that you're building in C# or Java. Typically Ruby focuses on the straight, narrow path and with that comes a dramatic turn towards "doing what you need to do... and no more". This resonates with me...
The part about Ruby/Rails focusing on "the straight and narrow path" really struck a chord for me.  Ruby, being a dynamic language, is very much on the "straight and narrow."  It dispenses with all kinds of things found in strongly typed languages like private, internal, protected, interfaces, etc.  These are things that are usually considered very important in a strongly typed language, and practices like DDD, but Ruby doesn't really bother with them.  Ruby favors documentation and convention over strict control.

Rails has a similar story.  It uses the Active Record pattern for its data access, which requires a 1-1 correspondence with your database.  Further, the models don't even really exist!  They're built dynamically from the schema of the database tables.

If you compare ASP.NET MVC to Rails one of the differences you'll quickly discover is this concept of a "View-Model". ASP.NET peeps seem to like these, whereas I haven't found a Rails sample anywhere that uses these.  Both Active Record and this lack of a View-Model are accomplishing the same thing: removing abstraction in favor of directness and simplicity.

Now lets step back from this for a second and ask a question.  Who in there right mind would want to have to deal with things like class and method visibility and extra layers of abstraction, which more often than not appear to be just duplication?  No one!  No one would want to deal with these things!  It's extra work!  I _hate_ extra work!

So why do we do it?  Why does DDD make a big deal out of private constructors and Factories?  Why does Fowler recommend the Data Mapper pattern over Active Record?  Why do we create View-Models to separate our Views from our Models?  Why do we do all these things that seem to just make life more complicated?  Why don't we all take the straight and narrow path on all of our projects all of the time?

Certainly it's not as simple as the language we're using.  Just because you're writing in C# and Java doesn't mean you can't use Active Record.  And it doesn't mean you can't pass your Model straight to your View.  There is also nothing about C# or Java that forces you to use interfaces, or follow the Dependency Inversion Principle.  That said, there's also no reason why you couldn't use the Data Mapper pattern in Ruby, or create View-Models.  The language certainly HELPS with some of these issues, but it's not the real difference.  These are just patterns, and they apply equally well to any language.

The reason why we introduce this complexity and divert from the straight and narrow path in our technical approach is actually due primarily to non-technical reasons.  Here are some of the reasons I think lead us to adopt these "enterprise" patterns:

  • There are more than two or three developers on the project
  • You have more than 6 entities in the domain
  • The project has a timeline longer than 3 months
  • The developers aren't intimately familiar with the domain
  • The project is likely to grow in fits and starts
  • The team members are more likely to come and go

These are not technical issues but they have technical IMPLICATIONS!

The practices prescribed by DDD are a big deal if you're working with a large complicated domain with lots of potential for change.  If you're not, then you don't need DDD.  Fowler's enterprise patterns are a big deal for the same reasons.  If you know things are complicated, likely to change, and not possible for everyone on the team to grok completely, then you need to build abstraction into your code.  And you need to try to be as explicit as you possibly can about what the code does and how it works.  And you need to look for opportunities to prevent error and misunderstanding before it happens.  These things will allow you to keep things clean, organized, and ultimately make your project successful when you're faced with "enterprise" challenges.

This is obvious.  I'm sure you're sitting there (or standing) thinking, "duh!" or "when is this dude going to get to the point?" or "does this moron really think this is revolutionary?!"

My point is as simple as this.  Rails is awesome.  Simplicity is awesome.  But as I sit here in my ivory tower looking out over the landscape I see lots of quiet subtle backlash from people against the "enterprise-y" patterns in favor of the simplicity of Rails.  This makes a lot of sense to me because, as we pointed out, who would WANT to deal with the complexity of enterprise problems and patterns?  But it is easy to be tempted by the appeal of simple solutions to simple projects.  And certainly we should always strive to find the simplest solution that could possibly work.  But we can not close our eyes to the complexities of the problem or the environment in which we are solving the problem.  And we cannot allow ourselves to be boiled alive either.

So by all means, choose the right tool for the right job, but make sure you understand the job as well as you understand the tool.

Friday, May 7, 2010

Vim Commenting

Recently there has been some renewed interest in my series of posts on using Vim for C# development, so I thought I should add a few more posts to the series to bring it up to date.

You can find the introduction to this series here.

Visual Studio has a feature which allows you to select a bunch of lines of code and have them all commented out, or uncommented.  In my setup it is bound to Ctrl+k+c to comment and Ctrl+k+u to uncomment.

I use this particular feature pretty regularly, so I definitely wanted it in Vim, and wouldn't you know it, there's a plugin for that!  NERD Commenter.

With NERD Commenter installed you can select a bunch of lines of code (I typically do something like Vjjjj) and then type either
,cc
or
,c<space>
The first is the comment command, the second is the toggle command.  If you use the comment command you'll need to use
,cu
to uncomment.  If you use the toggle command you don't need to remember two commands!

That's all there is to it!

Now, the first step is to visually select the lines you want to comment or uncomment.  You can just hit j,k a bunch of times but there are usually better ways.  For example, if you want to comment out an entire method:
public void IAmAMethod()
{
  ... lots of lines here...
}
If there are lots of lines in  the method, you don't want to be hitting j all day.  Instead, with your cursor on the method declaration line, do:
Vj%
The % is the "match" motion.  So when your cursor is on the { it will find the matching }.

Alternatively, if you just want to comment out a group of text that is arranged in a paragraph:
public void IAmAMethod()
{
  ...paragraph of code...

  // I want to comment out this block of code
  ...more code...
  ...goes here...
}
For this you can use the "paragraph" motion.  With your cursor on the first line of the block, do:
V}
That will select the whole block.

Once again, we have approximated a feature found in Visual Studio, but made it even better with the power Vim!

Wednesday, May 5, 2010

Vim File Navigation

Recently there has been some renewed interest in my series of posts on using Vim for C# development, so I thought I should add a few more posts to the series to bring it up to date.

You can find the introduction to this series here.

In a previous post I talked about how to open and edit files in Vim.  That post discusses just the basics of opening files.  Since then I've started using the wonderful NERDTree plugin.  This plugin opens a small buffer on the left of your Vim window which contains the file system tree.  You can then navigate through directories and open files.  The nifty part is the NERDTree is just a Vim buffer, so you can navigate with h,j,k,l and you can search with / etc.  To see what I'm talking about, you can watch a demo of the NERDTree in action here.

Before I go on I should mention that Vim actually has a built in file system navigation plugin called Netrw.  NERDTree adds a few features and is in someways a bit easier to use, but Netrw is capable of doing all of this stuff and it's built right into Vim.

Using NERDTree has completely changed the way I work in Vim.  When I'm ready to start working, I navigate to my .sln directory in the terminal and I type
gvim .
This opens Vim with NERDTree showing the contents of the current directory.  From here you can navigate around and find the file you want to start editing.

When you open the first file NERDTree will go away.  If you want to pull up NERDTree so it's always visible docked to the left of your Vim window you can type
:NERDTree
To toggle it open and closed you use
:NERDToggle
That's kind of a lot to type. So to shorten it up I've mapped it to F2 by adding this to my vimrc:
" toggles NERDTree on and off
map <f2> :NERDTreeToggle<cr>
imap <f2> <esc>:NERDTreeToggle<cr>i
Now hitting F2 will open and close the NERDTree. Fast and easy.

So NERDTree is great for finding and opening files (you can even open files in splits with i for horizontal and s for vertical), but NERDTree can also manipulate the file system.

For example, to add a new file, put your cursor over (or in) the directory you want to add the file to and hit the "m" key.  This will open up a menu with some options.  Type a to "add a childnode" and then just type in the name of the file. This works for creating directories too.  You can also move (and rename) files as well as delete.

Sunday, May 2, 2010

Coding Style Preferences

I recently did a little poll on twitter and in my office to get a feel for what people's coding style preferences were.  The fun thing about coding style preferences is that they are completely irrelevant, and yet a topic that people can easily get pretty passionate about.

It was only a little poll, with 35 people responding to these few questions:

Curly braces?
  • On new line
  • On same line
Spaces in control statements (if, foreach, etc)?
  • Spaces outside and in ex: if ( this.HadSomeCandy )
  • Spaces inside only ex: if( this.HadSomeCandy )
  • Spaces outside only ex: if (this.HadSomeCandy)
  • No spaces ex: if(this.HadSomeCandy)
Spaces in method calls?
  • Spaces outside and in ex: someone.ShouldJustDecide ( "what", "is", "right );
  • Spaces inside only ex: someone.ShouldJustDecide( "what", "is", "right" );
  • Spaces outside only ex: someone.ShouldJustDecide ("what", "is", "right");
  • No spaces ex: someone.ShouldJustDecide("what", "is", "right");
Spaces in method declaration?
  • Spaces outside and in
  • Spaces inside only
  • Spaces outside only
  • No spaces
Spaces in method calls with no args?
  • No space ex: someone.ShouldJustDecide();
  • Space ex: someone.ShouldJustDecide( );
How many spaces in indentation?
  • 2
  • 4
  • 8
And here are the results:



So, clearly, the winner is spaces outside/no spaces as in:
if (who.Cares("about coding style?!");

An interesting observation here is that the people who "don't like spaces" are very consistent in their preferences whereas the people who "do like spaces" are much more varied.  This is evident in that of the 22 people who voted for spaces outside only in control statements, 19 also voted for no spaces in method calls.

Note that only 25 people answered the question about spaces in indentation because I added it to the poll later.  I expect the results would have been much different because it was the people from my office who didn't get to answer and our internal standard is 2 spaces.

For curly braces it was 22 to 13 in favor of braces on a new line.

There were answers for just about every combination, no matter how weird.  For example, some people put spaces outside and in for control statements but no spaces in method calls.

The sample size of this poll is too small to actually mean anything, but it is still interesting that the preferences line up pretty closely with Microsoft's coding style standards.  I didn't verify this, but I wonder if this could be influenced by Visual Studio's default code style settings.

Personally I was very much in the minority here.  For the last five years I've been a spaces outside and in/spaces inside guy as in:
if ( who.Cares( "about coding styles?!" );

I've also been a 2 spaces guy and if you go back to college I was a curly braces on the same line proponent.  I started doing the curly braces on a new line when I started full time at my job.  I recently tried curly braces on the same line when I started learning jQuery and I have to admit, I didn't like it anymore.  Could be just because my javascript is still pretty ugly though.

I'm also starting to second guess the whole 2 spaces thing.  I always preferred it because it made it so you could see more code.  But now that I've embraced the SOLID principles, if the lines of code in my methods were so indented as to cause a problem reading them, I'd suspect a "design" problem with that method.  And I'm starting to think that 4 spaces would make a pretty big readability difference, since it would be much easier to spot where indentations start and end.  I think its especially important if you do curly braces on the end of the line, or if you're writing Python or Haml.

Finally, I always liked the spaces in control flow because I believed it made it easier to read.  But when I was preparing this poll I wrote the different styles out side by side and I started to wonder if the spaces actually bring out the "noise" of the different characters...  I'm still not sure about this one.

This whole exercise also made we question WHY there is so much possible variation in the languages.  Wouldn't it be nice of the details of the language were done in such a way that there was 1 right way to do it and we didn't have to concern ourselves with silly details like where to put spaces?