Jon Kruger -
  • About Me
  • Blog
  • Resume
  • Values
  • Presentations
About Me
Blog
Resume
Values
Presentations
  • About Me
  • Blog
  • Resume
  • Values
  • Presentations
Jon Kruger
Ruby

Statically typed Ruby? Don’t call me a heretic

I’m wish I could hear people’s reactions to reading that title. I’m sure there would be a wide variety of opinions, from “don’t you understand what duck typing is?!?” to “why don’t use just use .NET”? Well, I do understand duck typing and I also use .NET, so hopefully this turns into a logical discussion.

I do a lot of .NET development. I practically grew up on .NET and statically typed languages, so my world consists of things like interfaces, dependency injection, and waiting for my code to compile.

If you use dynamic languages, you might thumb your nose at those other things, and brag how you don’t have to use those things in a dynamic language. This is all true, and every time I sit and wait 30 seconds for compile my mind drifts off to a land where I can write code and just run my tests without having to wait 30 seconds to all of my code to compile so that I can test 1% of it.

I love Ruby because I don’t have to have all of the ceremony that I have to deal with in .NET. I love being to able to design objects the way I want without having to structure it in a way that makes it testable. And of course not having to wait for code to compile completely changes the way you write code.

It’s not all rainbows and unicorns

Software development is a series of trade-offs. One thing I really love about Ruby is that you have a lot of freedom but it’s not as dynamic as something like JavaScript (there’s a difference between 1 and ‘1’ and true), but I don’t have all of the constraints of .NET. The trade-off is that I don’t have that check that makes sure that I’m passing objects of the right type into a method or makes sure that an object returns an object a given type. This is where people yell “DUCK TYPING!!!!!”, which is true. In .NET, a class implements an interface if it’s specified in the class definition, which means that it has to implement all of the methods of the interface. In Ruby, there is no explicit interface, and the interface is simply defined by the methods that an object responds to. That’s all well and good.

Do I want compile time checks in Ruby? Well, maybe. The argument against that is that I should have tests that test everything, and in most cases I will. Then you refactor something. You run your tests and they fail, but the failure message is due to something that happened much earlier in the test, and the failure is just exposing that a problem exists somewhere. Now you’re left digging to try and find the place where something is returning the wrong type, and sometimes this takes awhile.

As much as compiling in .NET can suck, the static typing really makes refactoring easier, in part because the refactoring tools are better as a result. I’ll just change stuff and compile and let the build errors tell me exactly where to go. This is about the only time I like compiling. But when you’re used to that check and then it’s not there and you realize that refactoring is a little harder, it makes you think.

I did something about it

If I can’t have compile time checks in Ruby, I can have runtime checks. Then when I run my tests, at least it shows me exactly where things are failing. But after you write raise "Expected Hash but got #{input.class}" unless input.is_a? Hash over and over, you start to feel like there could be a better way. But this is a little better than it was before.

People have thought about this

There has been some discussion about adding static types to Ruby 3, but it doesn’t look like it is going to happen. I suppose I understand, Ruby is a beautifully simplistic, yet powerful language, so I get it if some people aren’t on board with such a radical shift. There also gems like rdl that give you a way to implement runtime type checking.

Other languages have done this

TypeScript is basically JavaScript with static typing and compile time checks. Some people don’t like having TypeScript’s restrictions imposed on them, but most people that have used TypeScript seem to like it. Either way, TypeScript gives a nice blueprint of a way that statically typed Ruby could work (I’m sure there are nuances that make it different, but you get the idea).

Discussion is good

I’m sure that people will continue to debate ideas like this, and if anything it provides a good education on differing philosophies in programming language design and the pros and cons of them all. It’s also a good reminder that there is no perfect programming language, that every benefit comes with a trade-off, and there is more than one right way to get the job done.

October 10, 2016by Jon Kruger
.NET, Ruby

Retrospective – a year as a Ruby on Rails developer

I spent the last year or so working on a Ruby on Rails project and now I’m back in the .NET realm again. I’ve been asked to write about what that year working on a new platform taught me and how I’m applying it to .NET, so here goes.

I love the Ruby language

I really really like Ruby as a language. You can write good code in Ruby and you can write good code in .NET. But I can write much cleaner, succinct code in Ruby because the language has fewer restrictions. I can do all of the same things in .NET, but it might require factories, dependency injection, code generators, etc. The code ends up getting the job done, but there is a lot more code and it’s more complex. The best example I can think of is a set of factories that create objects for unit tests. I’ve seen many implementations of this in .NET, but none have approached the simplicity of factory_girl in Ruby.

UNIX command line

UNIX is very command-line driven and it’s designed to be that way, so you can do a lot from the command line. You can do a lot with the Windows command line too (certainly with Powershell), but for the first time I really mastered the command line, and I really liked it. Now when I’m in Windows I pretty much use the bash shell that gets installed with Git for almost everything.

On switching from .NET to Rails

I really like Rails, but Rails is different from .NET in a lot of ways. I had no trouble coming into an existing Rails team and picking things up quickly. There are a lot of similarities between Rails and ASP.NET MVC. But if you want to take an existing .NET team and all start doing Rails, you definitely are going to want to bring someone with Rails experience to help you. You have to learn a whole new stack (because Rails runs on UNIX). The patterns and techniques are the same, but learning a new toolset will take time.

This doesn’t mean that teams shouldn’t consider switching to Rails. I’m just saying that while that might be a worthwhile idea, it’s going to take some work. But now that I’ve gone through the exercise, if I had to start a new project and was either working on my own or could choose a team to work with me, I would go with Rails because I feel it’s easier to do things.

Ever changing frameworks

Rails is open source, and there literally is a gem for everything. The problem is that all of it is constantly being updated. So if you decide to use the latest version of Rails, there is a chance that all gems won’t work in the new version. The same problem happens when you try to upgrade to a newer version of Rails – now certain gems won’t work, so you upgrade those, and now other gems don’t work. It’s not a showstopper, but it gets annoying at times. At the same time, I’d rather have this problem than having to write more things by hand myself.

Your process will determine your effectiveness, not your language

It may be true that it’s faster to develop in Rails than .NET. But what has much more impact is how you develop software. You can write good code in .NET and Rails and you can write bad code in .NET and Rails. If you have shoddy requirements, if you are relying solely on manual testing, if your business users can’t tell you what they want, if your team is not writing high quality code, or if there are other impediments that keep you from getting things done, your effectiveness will be limited. Regardless of what platform you’re on, working on improving your development process because that is ultimately what will determine your success.

October 25, 2011by Jon Kruger
.NET, BDD, Cucumber, Ruby, TDD, unit testing

Why do we group our tests by file?

Most people I know put their unit tests in files that mirror the folder structure and filename of the actual class that is being tested. So if I have app/models/order.rb, I’ll have spec/models/order_spec.rb. The tests in the order_spec.rb file will test the code in the order.rb file. Every project I have been on, whether Ruby or .NET, has done it this way.

But have you ever thought about why we do it this way?

We do it this way on our project and I keep running into two problems. The first problem is when I am about to modify some existing code and I want to know what tests will test that portion of the code. The first place I look is the corresponding test file (based on the folder structure or filename), but that doesn’t always give me all of the tests for that functionality.

The second problem is when I refactor some existing code and the refactoring spans multiple classes. Now I have broken tests all over the place and it’s hard to reconstruct the tests so that they test the same business concepts that they were testing before. Often times the tests were testing a portion of the system of classes that I am refactoring, but were not as encompassing as they should’ve been.

Here’s the thing — when I write tests, I’m typically using the Given/When/Then style of writing tests, even in unit tests using frameworks like RSpec. I’ll have test code that looks like this:

describe "When completing an order" do
  it "should set the status to In Process" do
     # test code here
  end
end

That code tests functionality having to do with orders and is going to help me ensure that my code performs some business function correctly. But if you look at that code snippet, you don’t know what classes I’m testing. Yeah I know, it’s just an example and I left out those details. But the point is that it doesn’t matter what classes I’m testing. What matters is that my tests are testing that my code performs a certain business function.

That being said, why are we grouping our tests by file? Wouldn’t it make much more sense to group our tests by business function instead?

I already have ways to find tests for a given class. I can search my code for the class name, or if I’m in .NET I can do Find Usages and have a little window pop up that tells me everywhere a class (or method) is used.

If my classes were grouped in folders by business function instead, I get the following benefits:

  • I can see what tests exist for a given business function
  • It encourages me to write tests that test business functionality, not test data structures (classes, methods, etc.)
  • I can put all kinds of tests in there (unit tests, Cucumber tests, even manual test plans) — all in one place, all checked into source control
  • My tests document business functionality instead of documenting a class

Remember, code constructs like classes and methods are just a means to an end, our goal is to write software that provides business value and performs specific functions. So I might as well organize my tests accordingly.

(Disclaimer: I have never actually tried organizing tests this way. It makes sense to me and I think it would work great, but I might try it and find out that it doesn’t work. But if anything, maybe I’ll start a good discussion.)

June 27, 2011by Jon Kruger
BDD, Cucumber, Ruby, TDD, unit testing

Using Cucumber for unit tests… why not?

It seems that the accepted way to test in Ruby is to use Rspec for unit tests and to use Cucumber for acceptance tests (higher level functional testing). After doing a little bit of Cucumber, I’ve started to fall in love with the format of Cucumber tests.

Most Rubyists would probably agree that behavior-driven development is good (in other words, writing tests in a Given/When/Then format). We obviously do this in Cucumber (there isn’t much choice), but I’ve also written tests in this format in Rspec and in .NET.

I like BDD for two main reasons. First, I believe that software development is a series of translations. I want to translate business requirements into readable, executable specifications, then translate that into tests, then translate that into implementation code. Second, before I implement a feature and even before I write my tests, I try to write out what I want the code to do in English. If I can’t write out what I want to do in English, how and I supposed to know what I’m supposed to write in code?

Here’s my theory: if we agree that BDD is good, why don’t we write our unit tests in a format that is more amenable to BDD, that being the Cucumber format of tests? I’m not saying that we write acceptance level tests instead of unit tests, I’m saying that maybe we should write unit tests in a different format. Not only that, Cucumber tables give us a nice way to write more readable, data-driven tests. Here are a couple examples from the supermarket pricing kata (in Rspec and Cucumber).

Cucumber:

Feature: Checkout

  Scenario Outline: Checking out individual items
    Given that I have not checked anything out
    When I check out item 
    Then the total price should be the  of that item

  Examples:
    | item | unit price |
    | "A"  | 50         |
    | "B"  | 30         |
    | "C"  | 20         |
    | "D"  | 15         |

  Scenario Outline: Checking out multiple items
    Given that I have not checked anything out
    When I check out 
    Then the total price should be the  of those items

  Examples:
    | multiple items | expected total price | notes                |
    | "AAA"          | 130                  | 3 for 130            |
    | "BB"           | 45                   | 2 for 45             |
    | "CCC"          | 60                   |                      |
    | "DDD"          | 45                   |                      |
    | "BBB"          | 75                   | (2 for 45) + 30      |
    | "BABBAA"       | 205                  | order doesn't matter |
    | ""             | 0                    |                      |

  Scenario Outline: Rounding money
    When rounding "" to the nearest penny
    Then it should round it using midpoint rounding to ""

    Examples:
      | amount | rounded amount |
      | 1      | 1              |
      | 1.225  | 1.23           |
      | 1.2251 | 1.23           |
      | 1.2249 | 1.22           |
      | 1.22   | 1.22           |

Rspec:

require 'spec_helper'

describe "Given that I have not checked anything out" do
  before :each do
    @check_out = CheckOut.new
  end

  [["A", 50], ["B", 30], ["C", 20], ["D", 15]].each do |item, unit_price|
  describe "When I check out an invididual item" do
    it "The total price should be the unit price of that item" do
      @check_out.scan(item)
      @check_out.total.should == unit_price
    end
  end
end

  [["AAA", 130], # 3 for 130
    ["BB", 45],  # 2 for 45
    ["CCC", 60],
    ["DDD", 45],
    ["BBB", 75], # (2 for 45) + 30
    ["BABBAA", 205], # order doesn't matter
    ["", 0]].each do |items, expected_total_price|
    describe "When I check out multiple items" do
      it "The total price should be the expected total price of those items" do
        individual_items = items.split(//)
        individual_items.each { |item| @check_out.scan(item) }
        @check_out.total.should == expected_total_price
      end
    end
  end
end

class RoundingTester
  include Rounding
end

[[1, 1],
  [1.225, 1.23],
  [1.2251, 1.23],
  [1.2249, 1.22],
  [1.22, 1.22]].each do |amount, rounded_amount|
  describe "When rounding an amount of money to the nearest penny" do
    it "Should round the amount using midpoint rounding" do
      RoundingTester.new.round_money(amount).should == rounded_amount
    end
  end
end

A couple things stand out to me when you compare these two. First, if I want to run data-driven tests with different values, the Cucumber syntax is so much cleaner and more descriptive. Second, the “Given I have not checked anything out” section in the Rspec version is really long and contains two nested “describe” sections (many times you end up with many more than this). When you nest sections like this, it’s really hard to see the context of things or read the tests because the “Given” text is nowhere near the nested “When” sections in the code.

Rspec follows in the footsteps of previous unit testing frameworks that write test methods in test classes (or in the case of Rspec, something that resembles test classes and methods. But is this the best way, or just the way that we’re used to? We have been writing unit tests this way for years and years because we had no other choice. But that doesn’t mean that it’s the best way.

Here are the benefits I see of using the Cucumber syntax over Rspec:

  • The tests are much easier to read (especially when doing data-driven “scenario outline” tests).
  • The Given/When/Then text is all in one place (as opposed to spread out and mixed in with code).
  • It forces me to be able to write out in English what I want the code to do.
  • Any step definition that I write can easily be reused anywhere in any other Cucumber test.
  • The code just looks cleaner. I’ve seen a lot of messy Rspec tests.
  • Rspec doesn’t have a method that corresponds to the “When” step (unless I’m missing something), so you have to shoehorn it into before(:each) or the “it” method. (I’m not sure why this is, we figured this out in the .NET world long ago.)

To be fair, there are more BDD-friendly flavors of Rspec (like rspec-given). This helps you write tests in Given/When/Then format, but I still feel like all of the underscores and symbols and syntax is getting in the way of the actual test verbiage.

Favoring Cucumber is my personal preference and I know that there are some people that would probably disagree with my opinion on this, and that’s fine. But I’m really enjoying what Cucumber brings to the table, both in terms of functionality and the syntax.

December 13, 2010by Jon Kruger
.NET, Ruby

Ruby on Rails vs. .NET: Don’t take it personally

As I’ve written these Ruby on Rails vs. .NET posts, I was not expecting some of the comments that I got. Not that the comments I got were not bringing up valid points, but I felt a tension in some of them. The same is true about other similar RoR/.NET posts (like this one — read the comments).

I feel like this is disintegrating into a religious us vs. them debate. I had no intention of it ever being this way, nor should it be in my opinion. I’ve just been stating my preference and explaining the reasons why.

If you prefer .NET over Ruby on Rails, I have no problem with that! If you’re better at .NET or it’s a better fit than RoR for what you’re doing, I’m not saying you’re wrong. I personally think that RoR is a better web development platform than ASP.NET, but that’s just my opinion. I also don’t think that ASP.NET MVC sucks or anything like that, I’ve had a lot of success with it and it’s still getting better.

I think as software developers we need to at least consider other languages and platforms that we don’t use regularly because there might be something better out there. If anything, you’ll learn something that you can take back to your platform and make it better. You might not like what you find, and that’s fine, at least you can know that you checked it out. Not everything you try will be worth using.

You are not your language or development platform. You are a software developer who happens to have expertise in a certain language or platform. If someone even were to deride your platform (which I have no intention of doing), don’t take that as a personal attack. There are a lot of ignorant people out there in all walks of life, don’t let them ruin your day. Just because someone likes Ruby on Rails doesn’t mean that you are any less of a developer for choosing .NET.

At the same time, I’ve found a platform I like and I’m going to talk about why I like it, because on this blog I talk about things I like. Some people find this “proselytizing” to be annoying, and I’m sorry that you feel that way. I’m only doing the same thing that .NET developers did when they proclaimed that Silverlight is better than Flash and that Windows Phone 7 is the next big thing. There is nothing wrong with being excited about a platform, technology, or framework that you like. That doesn’t mean that you have to think the same as me or agree with me, and I welcome the discussion. But let’s try and be polite about it.

October 22, 2010by Jon Kruger
.NET, Ruby

Ruby on Rails vs. NET: The Active Record Pattern, is it OK?

Persistence in Ruby on Rails is done by most people through the ActiveRecord ORM, which follows and is named after the Active Record pattern. There are other Ruby ORMs (like DataMapper) that don’t follow the Active Record pattern, but they aren’t used nearly as much.

Some .NET people seem to sneer at Ruby’s use of Active Record. There is a .NET implementation of the Active Record pattern (Castle ActiveRecord, which is a layer on top of NHibernate). In .NET and Java, the Active Record pattern is somewhat frowned upon and is usually considered not as good as a more robust, flexible ORM like NHibernate or the Entity Framework where your database tables don’t have to look just like your objects.

Some people would say that the Active Record pattern violates separation of concerns because the entity objects know how to load and save themselves. One big problem in the .NET world is that since an entity object can load itself, it has to do so with static methods (e.g. User.Load(3)), which means that now you can’t stub that out in a test (if you’re in a static-typed language). In a dynamic language like Ruby you don’t have the testability problem because you can stub out class methods (analogous to static methods in .NET).

There are still more concerns posed about the Active Record pattern. Is it maintainable in the long term? What if you don’t want your database tables to look like your objects? What if I would rather have separate domain service classes to do the persistence? What about the repository pattern?

If you’re a .NET person, you have to think about life in a truly dynamic world, where you don’t have the testability issues. Are any of those other things really a concern? If you’re starting a new app, what are the chances that your database tables won’t look like your objects? In most cases, I would say slim to none! If you have an application where you have some data concerns that would require to make your data model have a different shape than your objects, then you can’t use ActiveRecord. If you want to use an object database like MongoDB, then you use an ORM that works with MongoDB (like Mongoid). If you’re building a new app on top of an existing database, you may need something that will allow you to do different kinds of custom mappings (although you might be able to shoehorn it somewhat). But for the large majority of everyone else, what is the real concern?

The added flexibility that something like NHibernate or DataMapper gives you comes with a price — added complexity. Fluent NHibernate and some of the new Entity Framework stuff allow you to do convention based mapping so that it takes away a lot of this pain. If your domain model objects have a different shape than your database tables, you could have performance concerns (although not always).

What you get from ActiveRecord is simplicity, and simplicity is worth something. When you use ActiveRecord, you are essentially saying that your database and codebase are under your control, so you can have your database tables match the domain model objects using certain conventions. Your database becomes a very thin layer that does nothing more than store and retrieve data, and all of the business logic is in the business layer (where it should be in my opinion, regardless of your ORM). If you have to change your domain model objects for some reason, you change the database too. So I’m not constrained by my database because all of my logic is in the business layer, which allows me to easily change either layer whenever I need to. The benefit to this is that you don’t need to write any code to map your objects to your database and you don’t need as much hand-rolled SQL (you’re always going to have hand-written SQL for some queries no matter what).

The Rails project that I’m currently on is four years old. We use ActiveRecord as our ORM. I don’t see any situations where it really constrains us at all or makes our code less maintainable. I think it makes things simpler because it is assumed that the database tables and domain model objects look the same (you can override some of that if you need to). I feel like there is a lot of fear and uncertainty in the .NET world over ActiveRecord because the pattern isn’t really accepted in the .NET world (for good reasons). But that doesn’t mean that it doesn’t fit well in a dynamic language like Ruby, where I think it works quite well.

So if you’re a .NET person who is skeptical about ActiveRecord in Ruby, I would encourage you to have an open mind. There are other alternatives if it doesn’t fit your application, but in most cases I think it gets the job done quite well.

October 21, 2010by Jon Kruger
.NET, Design, Ruby

Ruby on Rails and the Single Responsibility Principle

Several people took issue with my last post about Ruby on Rails saying that my example violates the Single Responsibility Principle. Here’s where I stand on this.

The SOLID principles are principles, not hard and fast laws of software development. When applying the SOLID principles, common sense should rule. There are times when violating the textbook definition of the principles is OK (regardless of what language you are using). The ultimate goal of all design principles should be reducing the cost of change. Reducing the cost of change comes in many forms:

  • Being able to get things done faster because you have to write less code
  • Being able to get things done faster because it’s easier to figure out code and what you need to change
  • Being able to get things done faster because code is wrapped in tests so you can change it and not worry about breaking things
  • Being able to get things done faster because you have automated tests which decrease the amount of manual testing that you or your QA team needs to do
  • Being able to get things done safer by having abstraction layers in place so that changing code in one place doesn’t break something else
  • Having well defined requirements so that you don’t waste time on rework
  • Having business sponsors available to answer questions quickly
  • Many more reasons that I’m not thinking of

With this in mind, all of my design decisions, including how I apply the SOLID principles, need to reduce the cost of change.

Also, keep in mind that the SOLID principles were written with static-typed languages in mind (C++, Java, .NET). While a lot of the same principles apply in dynamic languages, you can’t assume that everything is the same. In fact, the “I” and “D” of the SOLID principles arguably don’t apply to dynamic languages at all.

Several people said that my Ruby class violated SRP because it mixed class behavior, database mapping, and validation all in one class. Again, this is where I would take issue with your application of SRP. Here is the Ruby class in question:

class User < ActiveRecord::Base
  belongs_to :user_status
  has_many :roles, :through => :user_roles
  validates_length_of :name, :maximum => 100
  named_scope :active, :conditions => ["user_status.id = ?", UserStatus::ACTIVE]
end

On my last .NET project, I had domain model classes like this:

public class User : Entity
{
    public virtual long Id { get; set; }
    [Required("Name"), Length(50)]
    public virtual string Name { get; set; }
    public virtual IList UserRoles { get; set; }

    public virtual bool IsInRole(string role)
    {
        // code here
    }
}

I was using Fluent NHibernate as my ORM on this project, so I had a database table that looked like this object. So in this case, I have class behavior (IsInRole method), validation (the attributes on the Name property), and implied database mapping (using Fluent NHibernate conventions). How is this any different than my Ruby class?

Some people might argue that the textbook definition of SRP would say that I shouldn’t put validation attributes on properties like that. What is your other alternative? Write a line of custom code in an IsValid method or in another validator class, I assume. Is that reducing the cost of change? If I write custom code, I have to write a test for it. If I write boilerplate stuff like “[Required(“Name”)]” or “validates_presence_of :name”, that is so simple that I’m not going to write a test for it because I don’t think I gain anything from doing so. If I can add a whole bunch of behavior in just one line of code, then potentially violating the textbook definition of SRP is OK with me because it’s way easier to do it that way and it just makes sense.

Back to my Ruby class. My class knows how to load, save, and delete itself. In .NET, I would say this is a bad thing. First of all, I wouldn’t be able to stub out the database in a test (which I can in Ruby because I can stub out anything). Second, if you have multiple entities that do things a certain way (e.g. multiple entities that need to be cached when loading, saving, or deleting them), you would have no easy way to do that without duplicating some code (in Ruby, I can create a module and include it in a class, and in that way I could override a method like “save”). Third, I would have a direct dependence on the database, which violates the Dependency Inversion Principle (which doesn’t apply in Ruby, because all I’m depending on is some class out there with a method with a certain name, as opposed to .NET where I’m depending on a method in a class in an assembly in a .dll with a specific version). So as you can see, your domain model takes on a much different shape in Ruby vs. .NET. Both ways have their pluses and minuses, but each way is the best way for the language that you’re using.

There is one area where I see an interesting clash of Ruby and SRP. Because I don’t have to use dependency injection and because I can stub out any method in a test, it makes sense to put all methods relating to an entity object into the entity class itself. This just makes sense, and TDD would lead you in that direction. Doing this will lead you into having some really big domain model classes though.

Would this violate the textbook definition of SRP? I would say yes. You run into some of the issues that you have with big classes (harder to read). In .NET, we would argue that we should move a lot of this behavior into domain service classes, which would be smaller and easier to use in other classes (by taking the interface into the constructor of the class that was going to use it). In .NET, you have to pull things out of the entity object in order to be able to stub it out in a test, so at that point you might as well go the rest of the way and make small classes. But if you had the flexibility of being able to stub out anything in a test and you had Ruby-style mixins in .NET, would you really do it this way? One could argue that the .NET way of doing things in domain services is an example of Martin Fowler’s anemic domain model anti-pattern.

In both languages, you are making a tradeoff. In .NET, we are saying that testability is more important that potentially having an anemic domain model and having model behavior scattered around in domain services. In Ruby, we are saying that we would rather have all of the behavior in the entity class itself because it makes sense to have it there (we don’t have to worry about testability because everything is testable), even though we could end up with some big classes. Neither way is necessarily wrong, it just depends on the language you’re working in. In some cases, the .NET and Ruby communities have generally agreed on their own “best practices” and ways of doing things, and that’s just how people do things in those languages, often because the languages and frameworks make it easier to do it that way.

In summary, it depends, and use common sense. Remember what your goal is — to deliver working software. Your architecture is not the deliverable, and it’s not what makes money for the business. Flexibility, design patterns, abstraction layers, and the like often come at varying levels of cost. It’s up to you decide if it’s worth it in your situation.

October 19, 2010by Jon Kruger
.NET, Ruby

Ruby on Rails vs. .NET: Doing more with less

One thing that I quickly noticed about Ruby on Rails is that you can do a lot more with less code. This is one of the benefits of working in a dynamic language like Ruby that does not have as many restrictions as a static typed language. The end result is that you have smaller methods, more descriptive code, fewer chances to create bugs, and it becomes easier to get things done. Let me show you what I mean.

Let’s say that I have a database table that looks like this:

create table Users
(
    id int,
    name varchar(100),
    user_status_id int,
    created_at datetime,
    updated_at datetime
)

My Ruby class looks like this:

class User < ActiveRecord::Base
  belongs_to :user_status
  has_many :roles, :through => :user_roles
  validates_length_of :name, :maximum => 100
  named_scope :active, :conditions => ["user_status.id = ?", UserStatus::ACTIVE]
end

My class only has 6 lines, but it does an awful lot. Let’s go through it line by line:

class User < ActiveRecord::Base

Because I have a table in the database called "Users", I now have the following methods on my User class:

  • id, id=, name, name=, user_status_id, user_status_id=, created_at, created_at=, updated_at, updated_at=
  • find, find_by_id, find_by_name, find_by_user_status_id, find_by_name_and_user_status_id, find_by_id_and_name_and_user_status_id, and any other combination of columns I might want to query on

Because I derive from ActiveRecord::Base, I inherit a lot of data access methods like save, delete, destroy, and many more.

All I've done so far is made my class declaration! Look at everything I'm getting for free.

belongs_to :user_status

My User object has a many-to-one relationship to the User_Status table (and it's corresponding UserStatus object). I now have the "user_status" and "user_status=" methods on my object. The user status will be lazy loaded, so it won't do any database queries to get the user status until I actually need it.

has_many :roles, :through => :user_roles

My User object has a many-to-many relationship with the roles table, and in the database there is a user_roles table that serves as a mapping table. I now have a "roles" method on my User class that will give me the list of roles, and I can add new roles to the collection without having to worry about creating anything for the mapping table.

validates_length_of :name, :maximum => 100

Name is required and cannot be longer than 100 characters.

named_scope :active, :conditions => ["user_status.id = ?", UserStatus::ACTIVE]

Now I can write "User.active", which will return all active users. This is equivalent to User.find_by_user_status_id(UserStatus::ACTIVE), but now I've abstracted away that concept of an active user so that other classes don't have to know how the internals work.

end

OK, well, every language has to have some ceremony.

I haven't created any methods yet! Already my object has all of the data access methods that it needs, it will validate the object before it saves, it knows about related objects, and I abstracted away the concept of an active user.

Note that not only have I been able to do all of this with very few lines of code, the code that I did write was very simple and readable. Since the code is so simple, I'm not going to write unit tests for it either (the tests would basically be the same one line of code as the implementation code in most cases).

All of this means that I can do things much easier than before. In .NET, I would've had to create finder methods by hand. I would've had to add all of the properties that match up to my database columns by hand. I don't know how I would duplicate named_scope in a .NET ORM, maybe it's possible somehow. I've never found a way to do it. Maybe I would have to write a stored procedure.

To sum it up, all of the boring crap is done for me and I can pretty much immediately start writing code that provides business value, which is what we're getting paid to do. No ADO.NET, no more mapping my database table to my entity object, no more modifying several files just to create the same kinds of methods that I have to create for every new entity object that I create.

All of this is helping me to achieve what I've always wanted in software development: the ability to write code that says what I want to do and does it without having to do lots of typing.

October 19, 2010by Jon Kruger
Ruby

My life as a Rubyist: a 4-week checkpoint

I’m 4 weeks into my Ruby on Rails gig and so far I’m loving it. Ruby on Rails is an awesome platform for developing web applications and it allows you to do things really easily. The Ruby language itself is extremely flexible. It has far fewer restrictions compared to static-typed languages, which enables to do things that you would’ve never thought of doing before. (If you’re curious, watch these screencasts on the Ruby object model and metaprogrammming, it’s some real mind-bending stuff).

The app that I’m working on is 4 years old, yet the codebase is probably the cleanest brownfield app I’ve ever worked on. The team puts a lot of emphasis on writing clean code and doing things right. I’m excited to work in a place where this is valued so much.

I noticed really quickly that there were very few really long methods in the codebase. The more I thought about it, I realized that this is not just because the team is making a concerted effort to write small methods (although that is part of it). You can do a lot in Ruby with not a lot of code, so you don’t need to write as much code. This leads to smaller methods, more readable code, and less code that needs to be written.

TDD is much more valued in the Ruby community. At JRubyConf last weekend, when they asked how many people in the audience practiced TDD, at least half of the people raised their hands. Everyone on my team knows how to do TDD. JRubyConf had three sessions on advanced TDD topics. None of them felt the need to convince people why TDD is good.

There are many more reasons why I like the Ruby on Rails platform (much more on this later). When you can do things using less code, there are countless open source packages that you can take advantage of, and when all of the tools you need to run tests, deploy your app, and migrate your database are already taken care of, you’ve drastically reduced the cost of change and developing applications (and don’t just take my word for it).

I’m not leaving the .NET world forever, but the Ruby on Rails world is more aligned with how I feel software development should be done (particularly when it comes to Agile, TDD, and software craftmanship). This doesn’t mean that .NET is bad by any means. But when it comes to developing web applications, Ruby on Rails has been quite an enjoyable experience.

October 11, 2010by Jon Kruger
Ruby

JRubyConf recap

When I started at my Ruby gig last month, my co-workers encouraged me to attend JRubyConf. I am really glad they did.

This conference was exactly what I’ve wanted from conferences in the past:

  • Primarily expert level talks on technologies that we already use (or new versions of technologies that we already use)
  • A good amount of inspirational or non-technical talks
  • Three talks in a row on testing! (and none of them were intro-level)
  • Most of the room raised their hand when someone asked how many people do TDD

The Ruby community is very willing to learn new and better ways to do things, and learning is encouraged and appreciated. This is very clear from the way this conference has been run, and it’s not being done in a condescending way. The bar for conferences that I attend has been raised quite a bit now.

Jim Holmes has been promoting JRubyConf (which has been known as eRubyCon in prior years) for awhile now, even for people who didn’t do Ruby. I would definitely second that, a .NET or Java person could learn a lot from seeing how things are done in Ruby (and the less technical talks apply to anyone). However, you may leave frustrated if you’re not currently able to use Ruby at your day job!

October 4, 2010by Jon Kruger
Page 1 of 212»

About Me

I am a technical leader and software developer in Columbus, OH, currently working as a Director of Engineering at Upstart. Find out more here...

I am a technical leader and software developer in Columbus, OH, currently working as a Senior Engineering Manager at Upstart. Find out more here...