I got involved with a back and forth on twitter today about rails, and ultimately I realized that there was no way to give my full opinion of the problems facing the rails community in 140 byte snippets. I’m not saying my opinion is the end all be all, but I have lead probably half a dozen rails projects and I did speak at RailsConf 2007.
So here goes, my unvarnished opinion of the problems facing the rails community:
- The community
- Totally decentralized, egocentric documentation
- Excessive reliance on ORM
- Pure ruby is the answer to everything
- Fragile ecosystem
- rexml violating the xml spec by totally ignoring the encoding of documents parsed by it.
- gem silently failing (not returning the proper unix return code) and thus allowing some of our instance launches to blow up without a reasonable way to catch it. (And as a note, when you have to automatically install large amounts of gems from rubyforge, it chokes a *lot*).
- Innumerable gems regularly break api compatibility even in minor releases (I’m looking at you Rack). When you add calls, you can’t just remove them between 0.9.2 and 0.9.3, it’s damn unprofessional.
- i18n has been a real problem right from the beginning.
- Passenger’s ApplicationPool choking and never coming back, forcing you to restart apache once a month
- Constant movement from one webserver to another. It’s damn frustrating to have to switch web servers every 3 months as the community hops from one the the next, as everything else gets filed in the community folder for utter crap. At that point it becomes damn hard to find support for problems. First it’s lighttpd, with mongrel, then thin, then nginx with thin and on and on. Somehow people need to support this mess. Apache works, is well supported, can be very lean, and basically every systems person on the planet knows how to work with it. Hint: as a programmer, it’s not all about you. Your applications need to be supportable; running away from standards for the sake of being different is dumb.
- Generates bad, bad habits in devs
- Creates a view of the world that implicit is good. This goes all the way to the language itself and the silly fact that explicit returns use more processor power then implicit returns.
- Creates a view of the world that clever is good. Anyone who has maintained software for a few years should be able to tell you, clever is bad, very bad.
- My personal least favorite, the technological abortion known as Single Table Inheritance. Admittedly, even the community is now arguing for people to not use this. STI is a wretched way to bind a database with an object model, it encourages sparse tables as well as overloading of tables. Both of these things will bite you in the ass down the road.
- Convention magic
- Rails hype will kill ruby
The community is the single most ego centric community I have ever seen in a decade and a half hanging around the greater free/open source movement. Everyone remembers Zed Shaw ironically (but deservedly) ripping into the rails community for it’s overblown personalities. But numerous other examples abound. How can I possibly view the authors of a monitoring framework with the name God (and a tagline “like monit only awesome”) as anything other then a people with enormously expanded and wholly unjustified egos? How can I possibly take HAML seriously when the main dev‘s bio starts off with “Hampton Catlin is one of the best people in the world. Flat out.” Seriously? One has to know that this guy is going to give any production problem you have very serious attention</wry>
No other way to say it, the rails community is obsessed with personal branding, not with being a helpful community. Is there any centralized site that has a good set of user commentable docs covering most extensions? Php has that, and it’s part of why it’s still a defensible choice for writing web apps despite its numerous other flaws. The end result is that when you google for just about anything having to do with rails code, the first five items are all personal blogs
With rails, the community doesn’t build any sort of centralized corpus of knowledge, what they all do is write a blog entry about such and such technique, or how they fixed a problem. The problem here is that nearly all of this knowledge is outdated, and impossible to tie to any one version of the application stack. So instead we get tons of blogs with disjointed suggestions that take you in the wrong direction whenever you google about an issue (sure, this solution worked in 2.1, but not in 2.0 or 2.3). Too bad it’s in a blog without with the applicable version number instead of in a comment at the end of the documentation like mysql or php.
I’m sure you have all heard of the N+1 problem. Sure, lots of devs will tell you that it’s simple to avoid, but based on all the teams I’ve evern worked on, all it takes is one lazy programmer and all of a sudden your templates are taking 7000+ queries to render. It’s no wonder the rails community seems to think sql is slow. Hint: the answer isn’t memcached, the reason your rails site is slow is because the sql it’s running is craptastic. 99.999% of rails sites could be vastly improved by just hiring one or two people who actually understand relational databases. The part that I really just don’t get is that sql is much easier then coding, and RDBMS is not rocket science, but it’s treated like this big hideous bear that your developers have to hide from.
The community is utterly obsessed with pure ruby, and looks down on impure extensions that are wrappers around solid C libraries. This results in a general race to the bottom for speed, stability and maturity. The unix world is packed with easy to integrate, solid libraries. Libxml-ruby is nearly two orders of magnitude faster then rexml, and has top notch compliance with the xml spec. Yet somehow rexml is the standard and libxml-ruby is the red headed step child.
Now, I’ll be the first to admit that the rails maintainers shout far and wide that rails isn’t enterprise ready, and it really truly is not. Over and over I have gotten bitten by the myriad of flaws in the rails ecosystem. Any one specific issue I’ve dealt with could have been fixed in version such and such of some gem (or it’s even worse with rails plugins.) This complaint is not about specific flaws so much as the whole ecosystem feels like it’s standing on a very fragile foundation. Some examples of the ways we have gotten bitten over the life of the multiple rails projects I have been involved with are:
And just to reiterate, some of these could be actually fixed, or hell, they may have always had a *way* to work right, but the default was broken, and caused project problems that never should have existed if the rails community could ever get around to implementing a spec as it is written.
Magic is the core of rails, and seems to be one of it’s biggest selling points. The problem is, there’s simply no place for magic in a world where people need to actually support your code. Explicit configuration and code is much more useful to operations folks who aren’t familiar with the codebase, framework, and language. Even if you use your developers to support your app, when they rely on a bunch of clever magic it can make for longer outages while people have to figure out what implicit thing they are failing to take into account.
Ruby could be a decent language. It has a lot of awesome things going for it. In a few years it really will be ready for real heavy lifting. At least that was ruby’s future. Rails has taken over the show. The Rails community is the ruby community, and it has not set ruby on a course to be a truly dependable language. Instead as rails project after rails project fails in all sorts of business environments, it is creating a permanent bias against the language in the management staff that oversees projects in american business. I’ve personally seen it in multiple companies, and expect to see it in most shops that are today fiddling with rails.
July 13th, 2009 at 4:12 pm
Ok. Let’s take it from the top:
1. It’s true that there are some egotistical personalities in the Ruby community, but the examples you cite are open, explicit jokes. I doubt you’ll find many programming communities with no egos at all.
2. Yep. There is definitely a problem with an inadequate source of centralized documentation. I think your position that it’s “egocentric” is misguided. It’s more a product of it being *easier* to put something up on your own blog than try to work on a community-wide solution. I’ve personally started documenting more of the internals I’ve been working on in the Rails wiki (http://wiki.rubyonrails.org/rails/version3/start) and I hope that Rails 3 sees a shift toward better, more centralized documentation. We’ll see.
3. The n+1 problem was neatly solved by DataMapper over a year ago, and I suspect something like its resultset solution will make its way into ActiveRecord. I’m not sure if you’re aware of this, but ActiveRecord is undergoing something of a rebirth at the moment as a more sanely architected ORM (courtesy of Emilio Tagua). As Rails continues to mature and grow as framework it will continue to resolve problems it has had.
4. I hate to say this, but you’re flat out wrong about this. REXML is absolutely despised by most Rubyists, and there are three popular C extensions for parsing XML (hpricot, libxml-ruby, and nokogiri). RMagick, an ImageMagick binding, is quite popular as well. There is an interest in keeping functionality available in implementations that don’t have access to C libraries (like JRuby), but you’re not going to find anyone trying to do image processing in pure Ruby.
5. Gem versions and plugins are a problem that is solvable, and which we will solve. It’s going to require some ecosystem adjustment, but pushing people toward using Rubygems instead of plugins, and avoiding breaking things in minor releases has already started to happen as the ecosystem matures and should happen more readily when some of the underlying packaging technology is improved (I’ve been working with Carl Lerche on improvements to gem bundling for Rails applications that will make it easier for the community to do the right thing).
To some of your points: The Rails 3 packaging solution will not require installing large amounts of Rubygems from Rubyforge at deploy time, which should remove some of your pain. Rack suffered from some growing pains, but contrary to your other claims, the community backlash (especially from the Rails team) to those changes seems to have set them straight. Rails seems to have had a good I18n solution since Rails 2.2.
And finally, “constant movement from one webserver to another” was the Ruby community’s effort to find the best possible solution. Engine Yard, where I work, has used nginx+mongrel since we started (around 3 years ago), and still recommend nginx+mongrel. We’re evaluating and have had good results with nginx+passenger, but I hardly consider one move in three years to be a mad dash.
6. At this point you’re getting a bit into a religious argument. Python takes your position, that explicit is always better; I’ve personally found that Ruby’s approach makes it possible to create much better abstractions. But that’s just my opinion.
“Creates a view of the world that clever is good.” Actually, virtually all Rubyists I respect abhor clever code for cleverness’ sake. That said, you might be referring to abstractions, rather than purely clever code. Again, I consider that to be mostly a religious argument.
Single Table Inheritance is a pattern first described by Martin Fowler, and first implemented in Java. In fact, the first result on Google for Single Table Inheritance is not Rails, but a section on Fowler’s site about STI. That’s not to say that STI is great–it has its share of problems–but I think it’s a reasonably good thing that Rails has tried out new ideas. Many of them have worked spectacularly well.
7. The pejorative use of the term “magic” is hiding the fact that what you’re actually referring to are simply better abstractions. Rails provides a number of ways to describe things declaratively that actually improve code maintenance because the features work the same way every time. Ruby provides significant mechanisms to add functionality that effectively extends the language. The appropriate way to look at these extensions is to think of them as *language features* that should be learned and understood by anyone who wants to work with the codebase.
It is of course possible to be explicit about everything all the time. That produces a language like Java, where nearly half of your code is talking directly at the compiler, and may not even be used at runtime (String string = new String). In practice, though, the only way to use Java effectively is to write wrappers around it (like Spring) that give you more dynamic features.
8. Rails pushed Ruby in ways that it would almost certainly not have been pushed. Before Rails, very few Ruby applications were run long-term; long-running Rails processes have pushed Ruby into making GC improvements. It has pushed Ruby into creating alternative implementations, like JRuby, that make it usable in a number of environments. And despite your argument, a tremendous number of very successful Rails applications are running right now, serving a tremendous number of requests every second. If you’re putting forth the idea that Rails projects are more likely to fail than Java projects or Python projects, I’d love to see some real statistics, but the fact that some projects started with Ruby on Rails eventually fail is hardly earth-shattering.
—
It seems like you may have had some bad experiences, having grown together with the Rails community. As we have grown, I believe we have done a reasonably good job of identifying deficiencies and trying to resolve them, and I believe that the release of Rails 3 will go a long way (but probably not all the way) to resolving those deficiencies. That said, your post was overly hyperbolic and your criticisms, offered in a more constructive way, would probably have more effectively improved the situation.
Feel free to email me (wycats -at- gmail -dot- com) if you have any further thoughts or suggestions. I would love to work with you to resolve some of the pain that you’ve experienced.
July 13th, 2009 at 5:17 pm
Yedhuda, that’s quite the response, and I appreciate it.
1. Not much to say here. I agree, I just think that there are some fairly high profile obnoxious examples. I get that this stuff is partially humor, but it is also hubris, and it definitely rubs more then just me the wrong way.
2. One can hope. Given that there are plenty of blogs sitting on rails, it seems a relatively easy mashup to build such a system with an existing doco app, and the comment threading from one of those blogs. Given the plethora of projects the occam’s razor answer that I settled on was that such a system would limit the amount of self promotion that much of the community is doing, and thus has never been a high priority.
As a note, having worked directly with one of the biggest rails consultancies, I can tell you for a fact that this was the explicit reason why many of their members blogged their coding observations, to the point of taking our internal code and posting it on their personal blogs in an effort to drive traffic. The phrase personal brand was uttered over the course of that project regularly.
3. I did try to be relatively clear that some of the code based issues may have gone away. I still fully believe that there are any number of workarounds in the rails community for a ‘slow database’ that get solved with things like memcache, but could be easily and with less fragility (due to lower complexity in the system) be solved with some relativly simple SQL.
4. So this gets into yet another problem that I’ve noted. My stated position coming initially from the java camp many moons ago is that an abundance of implementations of a public spec in a language is a sign that something is wrong. Java has this in spades with XML implementations. Ruby appears to have this as an issue with XML as well. My observation from the projects I’ve dealt with is that it’s less that all the implementations are flawed and more that writing your own is a better way to sell your personal brand, instead of patching the leading public implementation. Perhaps this is my bias, but the constant self promotion as the (my perception) default state in the community is almost certainly what started to initially push me away.
As a note, unless I’m crazy, hpricot is pure (or mostly pure) ruby, and nokogiri and libxml are the c based ones. It’s not a perfect measure, but it looks to me that if one can use searches as a proxy for usage, google trends shows that the ruby implementations are still in far more use then the other two (though rexml is starting to get below nokogiri: http://www.google.com/trends?q=libxml+ruby%2C+hpricot%2C+nokogiri%2C+rexml&ctab=0&geo=all&date=all&sort=1
I’m not saying that their aren’t C implementations that get used, but that there is a strong community bias towards pure implementations.
5. Of course the gem issues are solvable. The problem is that rails is being sold into organizations as an enterprise ready solution, and it’s not. As I said in the article, the rails maintainers do *not* tout rails as enterprise ready, big community members like the above hinted at large rails consultancy on the other hand does.
Nginx + mongrel may work fine for you. The problem here is that the community always seems to take some outside piece of software for reasons that appear to mostly be so that they can be different. Why rails didn’t initially target apache, bar none the most stable and supported webserver out there (that everything else ‘cept java targets as a top tier environment) I’ll never know. Instead we are stuck with a web server with half it’s docs in russian because it’s seen as lighter weight (which is a fallicy, but most people don’t bother to actually configure out most of the apache modules they don’t use. Without any modules, apache has a tiny footprint). There are strong reasons to follow conventional wisdom from time to time.
6. So I will admit that I have moved most of my personal development to python, but the ideas proceeded the move, not the other way around. The convention problem is that there are tons of undocumented conventions that you can run afoul of, or the documentation would be where you don’t expect it. Example: type as a column name. Sure, it’s documented that type is used for sti, but you have to know to look at the sti docs to find out why you get errors because ruby can’t instantiate a class with the name of the data in the column. This implicit behavior makes it very hard to bring people up on code because you need to know what *other* developers see as sensible defaults, which is always opaque. I’ll accept that’s it’s a philosophy difference, but it’s one that regularly costs developer time and money.
8. perhaps this is also a philosophy issue, but it sure as hell cost one of our guys a day while he tried to figure out where the config was the first time he used passenger. it picks up the config.ru from a directory that is *not* the configured web directory with magic. I get the idea behind sensible defaults, but to look for ../config.ru from the actual path configured is *not* obvious or sensible.
I think there is more to the java/ruby difference then just being overly explicit. The language itself (java) encourages really hard to follow patterns because it is missing a number of reasonable things (such as passing a method/procedure as a variable). Anyone who has ever worked with a class whose name ended in FactoryFactory knows just how broken Java is in this regard.
As a note, the ball of mud antipattern that is the large J2EE default is just as easy to implement in rails (and django and on and on). It probably has less actual code in it, but rails is no closer to meeting the unix philosophy of small programs that do as little as possible and chained via textual interfaces that java fails to blatantly meet. Yes, I do believe the Unix philosophy is a successful, maintainable and coherent philosophy (The Art of Unix Programming: http://catb.org/esr/writings/taoup/html/). I am of course open to other ideas but I think the large object oriented system inherently builds towards a ball of mud.
9. You are right, there are a ton of successful projects out there. There are also a ton of high profile projects (say like twitter) that basically need to gut rails out of their app to be able to handle real loads. I will fully admit that most apps do not need serious uptime to push a ton of data. But rails has pitched itself as a replacement for big applications, *not* for visual basic. If visual basic/ASP/PHP was what this stuff was marketed against, we wouldn’t be having this discussion, but it’s not.
Java is indeed a broken development platform in a number of ways, but that doesn’t mean responses to it are inherently capable of replacing it wholesale.
Thanks for your response, it was well thought out, and brought forward a number of points. Personally I think most development environments should be diverse, and use the right language for each job. I do think rails does the ajax thing quite well, and as templating goes, so long as you follow rules, it’s no where near the nightmare that jsp is. Rails has it’s place, but it’s not the top solution to every problem that it’s pitched as.
July 14th, 2009 at 11:56 pm
Dude, Hampton friggin’ *invented* ASCII. A little respect is in order.
July 15th, 2009 at 7:32 pm
1. Community
The old school Unix hacker ethos brims with egotism. When the system has always been a meritocracy based on how much you know and what cool stuff you’ve coded based on what you’ve managed to figure out on your own, why would it be any other way?
There’s also a level of irony involved, see “haha, only serious”: http://www.azundris.com/about/hhos.xml
Also, when you’ve worked with the web stack long enough, you painfully understand the layers of crufty hacks-upon-hacks that-is-the-web. It doesn’t help that monolithic “enterprisey” mega-corps such as Microsoft and IBM have done as much as possible to make it even worse(intentionally or not). Web development is miserable. So along comes an extremely well thought out framework that actually makes web development fun again. No wonder Rails devs would have an ego–if you get hit by the zen master’s cane and receive enlightenment I’d say you’re entitled to at least some ego.
As for Zed, his online persona is a freakish outlier, so you can’t use him as the face of Rails egotism. Besides, his ego was too large for Rails and he’s since moved on to Python.
2. Documentation.
I suppose you prefer monolithic Java-style documentation? To say Rails and its ecosystem of gems and plugins changes rapidly is an understatement, and it doesn’t look like it’s slowing down any time soon.
It’s impossible to fully document a constantly moving target and is silly to expect it. Why is this a great thing? Because it shows the style of development isn’t set in its ways, but is instead evolving and throwing multiple attempts at solving numerous problems until the right one sticks. RTFM has become LMGTFY. Perhaps this change reflects a generational shift, as documentation itself no longer matters as much as discovering how other coders are using the software. I rarely need to venture beyond a few Google SERPs to get exactly what I need. Rails is very social software.
3. Excessive Reliance on ORM.
You say “sql is much easier than coding.” Have you ever worked on a super-massive non-ORM app code base comprising ~35k lines of code just for several hundred models, managing nearly 500 db tables spread across 10 separate databases(Oracle, Mysql, and MSSQL), all containing about 3k unique SQL queries hard coded *throughout* the code? Oh and did I mentioned the .01% unit test coverage? No?
I have, and let me tell you, it was a total nightmare and I would have traded my own body parts for a drop-in ORM solution. Sure, there are corner cases where a raw SQL query doing a join across 6 tables is orders of magnitude faster than AR at its best, however 90% of the time ORM is “good enough.” Developer and maintenance time is worth far more than run time speed(Moore’s Law etc).
Also, there are major design decisions to account for if you find yourself dropping down to SQL just to make that big join query fast enough, such as: you’re probably doing something complex enough that you won’t be able to easily test it. Is that the kind of code you want to maintain down the road? Probably not.
4. Excessive reliance on pure Ruby.
I agree with you on this one, having a fine appreciation for dropping down to C when appropriate. Parsing of any kind is better suited for C. You use XML as the main example, but XML sucks, and everybody is coming to realize it. JSON and other micro-formats will soon supplant XML.
5. Fragile ecosystem.
I also agree. Ever changing dependencies and wack-a-mole gem breakage is a nightmare to fight. On the bright side, it’s the rapidly changing aspect of Rails–eventually as the ecosystem matures it will converge on stable APIs.
I don’t agree with you at all that Rails is not enterprise ready. “Enterprise” is a meaningless, undefinable buzzword used to spread FUD, and the word itself is a sort of shibboleth–if you use it in serious conversation, you’ve outed yourself as “not really getting software.” Recall, you could go back just 7 years or so and there were many large “enterprises” claiming that Linux was “not enterprise ready.” And look how right they were. All the so-called “enterprise” software I’ve worked on sucked. NIH and getting stuck doing things the wrong way ends up being worse than using better open-source alternatives. Case in point: M$ being crippled by their own support of backwards compatibility. They will never ship a successful OS again until they completely ditch the “enterprise” mindset. No wonder Google is successfully cutting off their air supply. Being pro-enterprise is essentially being anti-open-source. Again, it’s the hacker ethos: screw the system, it’s the bazaar that will win the war, not the cathedral. If haggling for the proverbial perfect black egg in the crowds of the bazaar is seen as a problem and not an advantage, then you’re missing a huge piece of the picture.
As for Apache, I’ll repeat the words of the lead yellowpages dev from his 2008 RailsConf presentation “The Big Re-Write”: “Apache is unsuitable for web serving in any production environment and only Nginx is the right way.”
Have you ever worked with an Apache conf that was literally 10k lines lines, contained 50 virtualhosts, a thousand rewrite rules, custom C modules, on top of all the other obscure crap Apache throws in which you’ll never use? I have.
By comparison, Nginx is a fresh spring breeze. Sure, it took a few years for Rails to ditch the nightmare complexity of Mongrel and the 31 flavors of web servers to settle on the right solution, but again, that’s an advantage. Java, Perl, PHP, ASP, etc, they are still essentially stuck doing things the same way they were in 2002. Dealing with change is easier in the long run than dealing with stagnation. Kind of like how emphasizing testing is better in the long run than not doing it at all.
6. Generates bad, bad habits in devs.
Convention over configuration is better. Richard Feynman humorously describes the essence of the problem in his “Surely you’re Joking…” book. He recalls his time managing the team running one of the first computers at Los Alamos. He describes “the computer disease”: the propensity for techies to get pulled into an infinite process of tweaking and customizing computers to do anything *because they can*. Basically it’s “architecture astronauts.” If the convention serves 80% of the needs, how is that worse than needing to endlessly configure software to meet the most common needs? As a dev, who wants to be a factory worker, repeating the same actions over and over each day? You want DWIM, so you can spend your valuable time on intellectual problems.
Clever *is* good, but only when coupled with good design. Clever is what allows you to define implicit conventions so you can avoid the monkey-work and spend your time coding the fun stuff. Let me tell you, after working in large “enterprise” Perl code bases for many years, I can say there is no doubt that Ruby implicitly encourages much better design. It’s much harder to write obfuscated, unmaintainable code in Ruby than many other languages. As for bad habits, what other language community is so hyper-obsessed with testing?
If anything, that the single most important trait to have, and Rails is massively encouraging it amongst devs who would probably never test their code. I’d say the good habit of testing balances out any so-called “bad habits.”
7. Magic
Not knowing exactly what the code is doing *is* the point. The code gets out of the way so you can focus on real work and even creative endeavors. Do you complain that you don’t know what your compiler is doing to your high level code? No. Because you could care less about instruction optimization and low-level memory managment. The same goes for higher layers in the web stack–abstract out the most common actions so we don’t need to know the implementation details, which will be specific to every platform, environment, etc.
Also, don’t fear magic–there’s something to be said about being a smart developer and knowing what the framework abstraction is actually doing, knowing how to configure, debug and test it. Everyone else can just go program PHP and Flash. Given the major trends to offshore our dev jobs, and for management to further trivialize and commoditize development, anything that requires smarter people with highly specialized skill sets is a *good thing*: it’s job protection. Hard to be against that in our current quasi-depressed economy, right?
8. Rails hype will kill ruby.
The entire computer industry is just one leap from a hyped product to the next hyped product. It’s been this way for decades. And guess which products end up on top? Yeah, the hyped ones.
Your claim that there’s a tide of companies falling over dead because they used Rails is anecdotal at best. Look at the top programming books by sales this year. Look at the number of Rails conferences going on this year. Look at the sheer number of Rails startups. Look at the number of projects on github where people are sharing code. Look at all the other web languages and frameworks openly copying features of Rails for themselves. There’s a point when a thing is no longer mere hype, and instead is a mass movement. I’ll invoke the “wisdom of the crowd.” Recall that this pattern mirrors the same ascendence of Linux a decade ago, and now, Linux is the mainstream. Ten years from now, Rails will be the dominant web framework because it is so much more useful to people than the alternatives.
In conclusion, thanks for writing such a detailed breakdown of issues with Rails that you’ve encountered and thought deeply about. I’ve seen very few which have warranted a response, but you hit some good points for which I couldn’t help but to toss in my own .02ยข.