Jolie Rouge


all ur parentheses Я belong to me


Love Ruby, Hate Rails, but still use it — or Ruby vs PHP

Okay, that title was a bit extreme, I don’t really hate Rails. I don’t get why people feel the need to be so completely polarized about a framework, or a language. It’s either the best thing since sliced bread, or the worst, and nowhere in between. Still, most developers who aren’t Ruby purists, can tend to have a love hate relationship with Rails. Rails is easy to develop with, full stop. It’s practically impossible for you not to push out an app in AT LEAST 1/4 of the time it would take in straight up PHP. The problem is, PHP and Rails are apples and oranges, they aren’t the same thing, Rails is a framework built with the Ruby language, PHP is just a language. If you want a comparison, try CakePHP and Rails.

Saying that Rails isn’t as fast as PHP is kind of mind boggling. Rails is slow, and so is ruby, and it will never be as fast as PHP or faster, period. Unless PHP becomes abandoned, which doesn’t seem likely. PHP is 100% geared towards a Server Side Scripting language, from the ground up, it’s written directly into the PHP parser to handle HTML with embedded PHP tags. Ruby is a general purpose scripting language with addon modules for parsing ruby code in HTML, like ERB. Regardless of this, you’d barely notice how much slower it is in reality because at this point, it’s very much a matter of hundredths of a second difference (probably). That barely even matters in large scale apps, because the gains in ease and speed of development pay for the slight slowdown during high traffic or the need to have more servers or better hardware and so on. Bandwidth, storage, and processor cycles are wastable resources, you waste them and get man hours back, man hours cost more than bandwidth hours, so it’s simple math.

Developing with Ruby and Rails means you can pretty much halve your dev team on any project. Unless there’s only one developer, then halving that person is a federal crime that can pull the death penalty.

No one seems to point out why Rails is actually bad, they always try to attack Ruby, which is like calling a Hot Chick ugly just because you can’t get laid with her.

Here is a list of reasons why Rails has trouble being adopted, and will continue to have problems. Also known as the Why Facebook don’t use it list.

  1. The community: The Rails community is, to be honest, a bit mean and snobbish. They consider themselves a bit more l33t than they really are. I respect any person who sits at a keyboard and ships code. The rails community doesn’t really seem to be peopled by battle hardened developers. Web Development is a bit like war, we are all in the trenches, all on the firing line, as long as you are pulling the trigger and hit most of the targets you shoot at, you’re gold in my book.Many, but not all, Rails developers seem to take a bit too much delight in pissing on any alternate view of programming, they’ll be more than happy to tell you which Rules and Paradigm Standards you are violating, and why you are stupid for doing so. One of the main criteria for a narcissist is: Do you find yourself unable to explain things that are obvious to you to others? If so, then you might be a self absorbed narcissist.
  2. Rails Breaks Everything, Alot:The Rails team are very inconsiderate. It seems like they aren’t working on multiple large scale production projects that can’t just be pulled off the line to be completely refactored because they gutted the framework with absolutely no eye to backwards compatibility. This is, to be honest, the #1 reason Rails will never be a serious competitor in corporations, to the bane of many developers working for the man and forced to use Java or PHP for webapps.You can almost say that the Rails motto is: “Rails, yeah, because fuck backwards compatibility.” I have 3 production apps that are hopelessly outdated because the client won’t pay for the work needed to update them to the latest Rails. I have other production apps that have been going for 5 years without an update, and don’t need one, because they are in pure PHP. Many PHP language updates later and they are still cranking. Can you say that about a Rails app you made?PHP has had a : “Try not to break it” mentality from the beginning. If someone chooses your framework or language, they depend on you being a good citizen in the development world, and Ruby and Rails are not dependable citizens, they are flippant and flighty, and will change everything just to implement the newest and sexiest feature or programming idea.Rails claims to adhere to DRY, Don’t Repeat Yourself, but with every update, you’ll be back to the app refactoring (repeating) your code to fix all the bugs and deprecations/deletions they introduced. So while the initial development cost is small, the long term maintenance of a Rails app is much higher than a pure PHP application. In PHP you have to write alot, but once you’ve written it, you probably won’t need to touch it for a decade.For a group of people who think they “know best” they sure make a lot of changes. You’d almost think they are admitting they were wrong, not a chance.
  3. Meta-programming is Arcane: Rails is ALOT of metaprogramming. And no, I don’t claim to fully understand everything that is going on under the hood. If you have ever worked in a real production and corporate environment, you know you get all kinds of programmers with all kinds of levels of understanding. Keeping it simple so even the dumbest of us can grok the code is essential. Esoteric programming is irresponsible and inconsiderate to programmers who aren’t as “smart” as you. While I personally love elegant metaprogramming solutions, I know that very often, I can go too far, so when I am working with a team, I try to make sure that my code is written for the lowest common denominator of programming understanding.This isn’t entirely Rails fault though, and to be honest, if you are going to use a framework, you should spend at least a week reading the source code. Each release of Rails seems to get farther and farther away from reality in too many ways.
  4. RVM: RVM is a blessing to anyone using rails, or doing general ruby programming, but it shouldn’t be necessary. Rails is precarious at best in deployment and development, the slightest change means tons of obscure messages pouring out on the console before it unceremoniously exits. Managing all of those Ruby and Gem dependencies is a nightmare, in fact there are several tools like Bundle and RVM to help you out. But should it even exist. There is nothing remotely like this in developing in say pure PHP. Having to maintain software over the long term is a truth that programmers deal with daily, and Rails really only makes that harder in the end.
  5. ERB vs. HAML: Both actually suck. HAML is like the unwanted love child of CSS and Python. It sounds so good on paper, but in practice it’s just as confusing. Anyone who’s tried to edit a complex Python script knows what I mean.ERB is just as mysterious: read confusing, and ERB internals are a scary scary place. As long as you don’t deviate from the normal usage, you’re fine, but if you want to try anything fun, don’t, you’ll get some weird behavior. Such weird behavior is actually talked about in the comments of Rails with the various output_buffer finagling.What makes it worse is that Rails itself is about as Arcane. Their fanatical adherence to various programming standards means reading across several modules to track down what code does what, and even then it’s still bloody mysterious. I ran into this problem the other day while trying to track down exactly what Rails is doing when it caches partials, not the theory, the actual programming, after about an hour I just gave up.
  6. If you deviate from the norm, Rails is not you friend, Rails doesn’t want to talk to you, in fact it hates you and wants you to die and it doesn’t care if you are its baby daddy.You will get NO support from the Rails community, saying that you have a different idea on how something should be done, and have the willingness to implement yourself will be met only with scorn, disapproval and a miniature inquisition about why you’d want to do that.In some ways, Rails is a bit like that really sensitive and clingy girlfriend who’s totally sexy, but flies off the handle when you offhandedly suggest some area for improvement, or disagree with her about the words to her favorite song, or whether or not her cat can understand her…
  7. Scaffolding: It’s actually more important than you think! Considering that almost 90% of what is cool in Rails is there because it’s a part of Ruby, you’d think they would have a much easier code generation scheme that is absolutely dead simple to override and extend. I remember when I first watched DHH’s famous Blog screencast where, even though he says that Rails isn’t the scaffolding, and that it’s only a small part, it was essentially the scaffolding that sold people on it.Rails is opinionated development, okay, cool, rock on, that’s fine. But when it comes to view code, Rails doesn’t really have much of an opinion, and the one it does have is cumbersome, ugly and time consuming to deal with.  There is a right and a wrong way to handle views and templates, and forgetting for a moment that Rails, like all frameworks, is centered around destructive server side templates (There still isn’t a better way), the least it could do is provide some nice, DIV/SPAN based templates with an obvious and well defined class structure. Oh, and since we are on it, just make SASS the default.
  8. Whiny Nil:There is a bit of a debate as to whether or not this should even be there. It’s really annoying. One of the best things about PHP is the “If it’s null, weird things will happen, but it still runs.” Some people consider that an issue, but most of us consider it a feature.  It means that your entire site won’t be brought down by a single mistake and spurt out some error to a client.Why is this important?Great question. Let’s say you have a table of some objects and one of them has a price field. By some weird coincidence that you didn’t catch before you shipped your product, that price field isn’t zero in the db, it got set to NULL, and then Rails set it to Nil, and in your code you try to multiply Nil by say a quantity:  total = object.price * object.quantity, 999 times out of a 1000, it does it right. But that 1 time when price nil? will bring your site to a screeching halt, or at least a main page. This is something good in development, it lets you find bugs, but in production its absolutely unacceptable. Only critical/fatal errors should bring a site down. Ruby kind of prides itself that nil != 0, that’s fine and dandy when we are talking about abstract concepts.

    When we are talking about a price field, nil, which was NULL === 0 and should behave as such.

    In the end, this all comes down to a bit of a philosophical conflict, my philosophy about systems is very simple: Only fail when you absolutely must, if you can regain sanity in the application, do so.  If some called a Fixnum method on a nil, they probably thought the nil was a Fixnum, or Float and just don’t know, quietly and secretly notify the developer and just pretend nil is 0. Is that so hard?

    During an abstract discussion, throwing an error on nil is, simply put, a very good idea, it helps to keep developers attentive. All things being equal, it’s a good thing. But all things aren’t equal, and what makes a framework worth using is not so much that prevents you from being an idiot, but sometimes rescues you from being an idiot.

    It is however trivial to override this error. The offender is activesupport/lib/active_support/whiny_nil.rb, just copy that code into an initializer, changing the top line to be: NilClass.class_eval do, and then add something like this to method_missing:

    if 1.respond_to? method and args.first.class == Fixnum then
      return 0
    end
    if ' '.respond_to? method and args.first.class == String then
      return 'NilString'
    end
    
  9. MySQL: Rails just doesn’t play as well with mysql as it could or should, anyone who works on internationalized apps knows that they are a byatch in any programming language, the problem is, when Ruby get’s it wrong, man is it complicated to make it work. We recently had a problem with encodings, data from the MySQL DB was being returned as ASCII-8BIT and practically none of the fixes seemed to work, encode! and force_encoding didn’t help. The problem was, the data in the db was stored as UTF-8, and using PHP we verified that the data was in fact being returned to PHP correctly. The problem was the mysql2 gem. The only mysql acsii-8bit to utf8 solution that did work in the end, though it is ugly and has some obvious gotchas is this:

    # Patching MySQL:
    # 
    require 'mysql'
     
    class Mysql::Result
      def encode(value, encoding = "utf-8")
        String === value ? value.force_encoding(encoding) : value
      end
      
      def each_utf8(&block)
        each_orig do |row|
          yield row.map {|col| encode(col) }
        end
      end
      alias each_orig each
      alias each each_utf8
     
      def each_hash_utf8(&block)
        each_hash_orig do |row|
          row.each {|k, v| row[k] = encode(v) }
          yield(row)
        end
      end
      alias each_hash_orig each_hash
      alias each_hash each_hash_utf8
    end
    
    # Patching ActionController:
    # 
    module ActionController
      class Request
        private
        def normalize_parameters_with_force_encoding(value)
          (_value = normalize_parameters_without_force_encoding(value)).respond_to?(:force_encoding) ? 
             _value.force_encoding(Encoding::UTF_8) : _value
        end
        alias_method_chain :normalize_parameters, :force_encoding
      end
    end