Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

MythBusting — Merb Style

The Rails team has lately been out in full force trying to bust some myths that seem to have come from the Merb community. In a reddit comment, in attempting to rebut a claim that Merb was significantly smaller than Rails, bitsweat made this “myth-busting” claim:

The merb stack is about 30KLOC; merb-core is half that. Rails minus Active Record is 46KLOC.

That seemed wrong to me, since I’ve recently clocked in merb-core at just 7,000 lines of code, and I know that merb-more plugins are relatively small, so I decided to do some counting.

My tool of choice: find lib -name "*.rb" | xargs cat |grep -v "^[[:space:]]*$" |grep -v "^[[:space:]]*\#" |wc -l

It may be relatively coarse, but it should be close enough to the actual figure to get us some real numbers. In case you need help there, I’m getting all Ruby files in the lib directory, catting them, then removing lines that are just whitespace or begin with “#” (comments).

Drumroll please.

merb-core clocks in at just 6,944. If you add in all of merb-more but auth, exceptions, and slices (features that Rails doesn’t have), that “bloats” us up to 13,322. If you add in those plugins (which clock in at a “massive” 2,282 LOC) we’re up to 15,604. Finally, throw in extlib (our “clone” of ActiveSupport) and we’re up to 17,291.

Next stop: Rails.

As per bitsweat, we did not count ActiveRecord. We also didn’t count ActiveResource or ActiveModel, which don’t have analogues in Merb.

Starting with humble action-pack, it clocks in at a “tiny” 12,126 LOC. action-mailer clocks in at a “miniscule” 6,405 LOC (take that, merb-mailer, with your bloated 216 LOC). ActiveSupport clocks in at 23,217 LOC. I wonder what they had to leave out to keep it so small compared to the extlib “clone”.

And finally, railties, a veritable smorgasbord of Rails extras, clocks in at 5,447 LOC.

merb-core + merb-more + extlib clocks in at 17,291. Rails clocks in at 47,195.

As you can see, it’s a tie.

Oh, and I forgot to mention that Merb contains rack handlers for mongrel, thin, ebb, fcgi, cgi, webrick, etc. which clock in at over 700 LOC. In Rails-land, that code is contained in the individual gems (such as the mongrel or thin gem).

UPDATE: When you remove the LOC that’s the result of bundled gems, it’s still a tie, with Rails clocking in at 23,923 and Merb clocking in at 15,009. See my Nov. 15 post for a more exhaustive treatment of modularity.

26 Responses to “MythBusting — Merb Style”

Competition is great!

Your count is also including several vendored gems that Rails includes. ActionPack has html-scanner, ActionMailer has text-format and tmail. ActiveSupport has Builder, i18n, memcache-client, tzinfo, and xml-simple. Clearly this equals about 30k lines and puts merb and rails on equal footing.

I’m not sure how accurate that will be (I’m not totally sure how, for example, you’re dealing with comments). Use something like sloccount to get better numbers since it’s language aware. I’m absolutely positive it’s still smaller, but I think you’ll get very, very accurate numbers that way.

Oh, just as an aside, the smugness doesn’t help your case. :P

Hey Yehuda,

I cloned the merb repos and did `find */lib -name ‘*.rb’ -exec cat {} \; | wc -l`. About 30KLOC. I hadn’t thought to include extlib.

I did the same with Rails’ Action Pack, Action Mailer, and Active Support, minus lib/*/vendor. About 46KLOC.

It’s a rough and probably useless measure, to be sure, but the 6000 vs 60000 lines anecdote smelled way off.

By your measure, but excluding bundled libs, Rails is 23923 LOC.

As you can see, it’s a tie ;)

@jeremy I consider so much bundling to be detrimental to the framework. I understand that it’s helpful in avoiding dependency conflicts, but it means that if a user happens to need a newer version of xml-simple, for instance, unexpected, weird things might happen.

Also, as I posted on reddit, it would be useful for Rails to define a small (6kloc’ish) subset that can be run without needing the rest. merb-core is that subset, and it’s a big win for people who do want a smallish framework.

Finally, modularity has its benefits, even regardless of LOC. I suspect that Merb will continue taking on modules (we probably will have an authz module) over time, but because they’ll be very separate chunks of code, it’ll always be possible to use just what is required, and be pretty sure about dependencies.

If my tone was too harsh, I apologize. I’ve just been somewhat frustrated by the claims that Merb is “almost the same size as Rails” when we’ve focused a lot of time and energy on keeping it compact and (more importantly) modular.

Yehuda, I’ve never heard anyone claim Merb is almost the same size as Rails. In fact, I’ve only seen the opposite (a bit of googling agrees). So I brought out the tape measure.

This whole thing reminds me a little of a juvenile school yard fight. How about we just get this over with and everybody compare c0ck length. Seems like that would be a more constructive use of our time than arguing over lines of code.

Frankly, LOC isn’t that important of a measure. What is important is that the code be easy to read, understand, and build upon, which may be tied to concise, clean, modular code, but LOC in and of itself isn’t significant. Also, small memory footprint and fast/efficient is also important ;)

So really, for production uses speed benchmarks and memory footprints are more important, and I think if Merb’s code is easy to understand it’ll grow to be more stable than Rails, and if it’s modular more people will want to use and extend it. Standing the test of time is most important, in other words…

Well put, nanodeath. And “BJ” too ;)

Hot damn, I didn’t realize Rails was so modular. What rake task do I use to remove all those libraries? Or, which rake task do I use to upgrade them?

Yehuda, I think the fact you haven’t corrected your claims in the main article is pretty lame. Come on man, be honest with yourself at least.

@frank what specifically would you like me to correct?

Why you guys don’t measure code complexity with flog and stop this silly “mine is smaller than yours”.

Well, I guess that only work for code and cellphones ;-)

@Yehuda – The needed correction is you have to subtract vendored lib LOC from the Rails numbers you show. I’m sure reading will help you understand.

If you think vendoring gems is wrong, then it’s completely different issue than this LOC talk.

And just so you know, Rails first checks if a higher version of the vendored gem is installed or not for every vendored gem, and loads the higher version if found. Apart from that, I think we all know who has had higher problems with gems/dependency conflicts –

@pratik checking for a higher version doesn’t work either. You actually need to use the dependency mechanism to allow gem author to state what versions of gems are acceptable.

The reason we’ve had “more” issues is that Rails defers the issues until runtime. By using bundled dependencies and plugins with no dependencies, everything *seems* to work at bootup, but weird errors crop up at runtime that are extremely hard to track down.

I’d prefer to be notified about dependency conflicts up front, even if it means we have to work to improve rubygems so it can handle more complex situations better.

Competition is great. I love and use both Rails and Merb. Thanks much to everyone who has contributed, innovated, etc.

Rails is getting faster… lately many of my actions are taking < 20ms.

Maybe there can be a mud wrestling ring at the next rubyconf where all the flamers can battle it out in real life… :)

Why’s everyone still talking about speed, when:

– most users don’t need it
– most apps are slow in THE RENDER PHASE

n.b. none the penis enlargers under discussion here do shit about that issue.

If you have a backend service that needs real speed, I wouldn’t use rails or merb. They’re both shit slow for that. In fact, I probably wouldn’t use any of the webservers you people use either, they’re also very slow. Firstly they do full http parsing (ouch), second of all, they’re synchronous (ouch).

There’s only a handful of us battling those issues, meanwhile you all enjoy yourselves bickering about stuff that doesn’t matter. Neither project will die as a result, you’ll just load up the spamtrains with more goo, and go to bed stressed one night and arrogant the next.


Uh, so the reason why we’re having this LOC contest is supposedly because less LOC makes it easier to understand and familiarize yourself with the code, right?

Write some fucking documentation. That’ll make it much easier than just writing compact code.

Talk about the pot calling the kettle black.


The pot calling the kettle black? Dude, read your comments again and see if you can spot the hilarious irony as I don’t think it was intentional.

Write some documentation? Do you mean like a $50 book from Pragmatic Programmers? Or like Django? :P

I meant @tomas. Sorry, Tomas.

Documentation is coming up, check the latest Merb news where documentation is addressed.

You’ll be happy to see one of the latest Rails core commits, by none other than DHH himself, here: (GitHub).

Be sure to read all of the hilarious comments that ensue.

Wait, you want …. what, something that handles the request/response cycle and is able of rendering a view in one of many formats, using one of various adapters, like ERB, haml, or whateverthefuckyouwant?

$ cat lib/sinatra.rb |grep -v "^[[:space:]]*$" |grep -v "^[[:space:]]*\#" |wc -l

Hah, it seems it isn’t a tie after all.

Oh wait, right, this is to see who has the biggest penis, not what framework you are most comfortable working with. Not to see which framework people relates better to. Or which framework gets the job done. Get back to work and stop wasting time with this shit, please :)

Er, sorry, 798 — 553 is in the branch were the framework is being rewritten, but since it’s not stable yet let’s not count it, it wouldn’t be fair, would it? ;)

Leave a Reply