magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Since lambasting someone for a less than fair Django and Rails comparison, I’d planned to do my own. To start with, my comparison is based on several days worth of Rails development and about a weekend’s worth of playing with Django, using the (currently four part) tutorial.

I’ve had this reviewed by both Rails and Django developers, but if you think I’ve misrepresented anything or left anything out then feel free to leave a comment and I’ll make sure to put it right.

Background

Rails is framework which emerged from the development of a web application, Basecamp. Django was emerged from the development of the highly successful Lawrence Journal World. Both applications were written in situations and organisations that historically would have ended up being written in Perl or PHP – but ended up being written in Ruby and Python respectively.

The fact that both frameworks were the result of development of specific applications means that both frameworks are focused on supporting those specific types of application. As a framework Rails has been around for little over a year, whereas as a framework in its own right django has only been public for around two months. Neither has yet made it to version 1.0.

Languages

On the face of it, the biggest difference between the two has been the choice of development language. Outside of Japan Ruby has made little impact despite having been around as long as Python – a colleague of mine once said that the number of Python programmers in London probably outnumbered the number of Ruby programmers in Europe and the US and he’s probably not wrong. Anyone having to consider which of the two frameworks is right for them is inevitably going to have to think about the task of hiring people and this may have an impact on their choice.

Ruby does seem to have some more powerful language features – it has slightly better closure support than Python (although perhaps not enough to be a differentiating factor) and the extremely useful mixins. Ruby’s OO support also feels much cleaner. Both support inheritance (Python supports multiple inheritance, which Ruby’s mixins more than make up for). But the requirement that self be passed in to all python instance methods drives me potty.

On the other hand Python has a much cleaner syntax (which given its background is no surprise) – more than once I’ve found myself using a third type of parenthesis in the same Ruby method quite validly, only for me to look back at what I’ve done and feel that I’d regressed to the bad old days of Perl. It would be nice to think that one day a language will come along which manages to add powerful features without making the code look like it’s been rendered with the wrong character encoding.

Ultimately comparing two languages that are so close (they’re certainly more similar to each other than Java or .NET) is going to come down to personal choice or a specific requirement. But for more indepth comparisons you’ll no doubt find many out there on the web.

Requirements and installation

Installing both Rails and Django is fairly easy once you’ve got the relevant interpreter installed. Ruby can make use of the excellent Gems system, which is something Python (and to be fair most other languages including Java) would do well to mimic.

Both also come with their own webserver for development purposes, which is great from a developer’s point of view. There should be anything stopping you from getting both up and running fairly quickly

Deployment options

Both Python and Ruby suffer from a similar global interpreter lock problem – basically neither the Ruby nor Python interpreters are completely thread safe. When running multi-threaded applications a lock has to be acquired by a thread before it can access any objects. That means that both Ruby and Python scale by using multiple instances of the interpreters rather than the Java approach of using multiple threads – as a result the deployment options are fairly similar.

Django’s current recommended deployment is using Apache and mod_python, although there is no reason why fastcgi couldn’t be used, or even an alternate server such as lighttpd (which is TextDrive’s current approach to hosting Rails).

One important point is that Django currently only supports Sqlite, MySql and Postgres (although support for Oracle has already been submitted to the project), whereas Rails supports virtually all the major relational databases.

Caching

Django’s heritage as a framework supporting large, high-volume websites shows through clearly in the built-in support for a variety of caching options. Rails’ own caching doesn’t seem as flexible. With Django multiple caching backends are supported (in memory, memcached, or DB) coupled with supporting caching at multiple levels – either for a whole site, a specific page or fragment (like Rails), or even a specific object.

Setting up a project

Both frameworks generate your project structure for you. Django actually has separate concepts of Project and Application (of which more later). Rails goes a little further – it also generates a build file and stub tests (I won’t call them Unit tests as Rails does, because they’re not). There is nothing to stop you testing Django of course – it’s just as testable as Rails – however it would be nice to get some guidance on how to do it. My feeling is many people new to testing are more likely to do it with Rails because it’s built right in and it’s well documented.

Adding models

In Rails, you define a table that represents your model, and then generate the stub code to create a Rails model that binds to the table. You are then free to build upon the stubs. With Django, you define your model in Python code, and have Django generate (and even execute) the schema for your model.

The fact that your Python code can be the canonical reference for your models means understanding can be simplified. It can seem odd to be adding code to a Rails model and not know exactly what attributes your model has without referring to the database schema. The fact that Django can generate the SQL from you model also leads to flexibility in development – for example a developer can use Sqlite which is fast use and trivial to setup, but deploying onto MySql or Postgres is easy as you can regenerate the SQL for your target database from the Python code – that the SQL for both databases might need to be different is hidden from you.

Early on your model will be constantly changing – I’ll often find myself writing some Rails code, need to add a new attribute to a model, have to change my (DB-specific) schema. With Django I change my model and regenerate the SQL. The only minor annoyance is that there is no equivalent of a model-specific SQL refresh – something that could drop a specific model’s tables and regenerate the needed SQL automatically. Instead you have to have the admin script dump out the SQL to the command prompt and run it in yourself.

Django’s generation of schema also extends to creating lookup tables for many-to-many relationships.

The downside to having Django generate the SQL schema is that there is more work involved in supporting databases – currently only MySQL, Postgres and Sqlite are supported, although I’d be highly surprised if support for other databases wasn’t on the way.

Django does seem to offer the ability to reverse-engineer models from an existing schema, although I don’t have information as to how sophisticated this is (for example to what extent it can determine inter-model relationships).

Another thing to note is that unlike Rails Django doesn’t allow you to manage your own transactions (although it is going to be added). I’ve not found myself needing it in my Rails or Django work to date, although as a J2EE programmer not having the ability to control this if I need to is a minor concern for me.

Interaction with the Database

Both Django and Rails have taken the decision to bind models to the database. Methods to save, delete or lookup objects are called on the models themselves. Neither specifically stops you from providing proper separation, but if you do you’re on your own. Going forward it will be interesting to see if either Rails or Django start providing the ability to have a clean repository layer as nicely as they do the current DB access, although it will probably require both of these frameworks to be used in more complex situations than they are currently.

One nice thing Django offers is the ability to write your own SQL in the model to access attributes. Rails does nothing to stop you calling SQL directly, but the fact that with Django you are doing this custom lookup in the same place as the definition of the other attributes (whereas with Rails it would be split between the schema and Rails model) results in something much cleaner.

Projects and Applications

A nice touch with Django, and another example of the environment in which it was developed, is that there is a project in which you can have pluggable applications. This should hopefully lead to smaller (Rails-style) apps being created, reused and integrated easily into a larger Django projects. This was something that was demonstrated wit LJWorld, with new parts being added incrementally without a need to deploy the whole site.

Controllers and URLs

With both Rails and Django URLs are mapped directly to code. Rails automatically generates stub controllers to map to the scaffolding (of which more later), whereas with Django you have to create them yourself.

With Django you use regular expressions to define URL’s that bind to your python code. That makes it much easier to create RESTful URLs – in fact all of the tutorials reinforce this. The fact that you have RESTful URLs happens to make controlling code simpler is just an added bonus.

By default Rails gives you URL’s in the form controller/method – but these can be edited using the routes.rb file to give you proper RESTful (or not) URL’s. Unlike Django’s pseudo mod_rewrite approach, Rails uses Ruby code to handle routing, which depending on your point of view could be considered more readable.

The URL to code mapping can be specified either for a whole project or (more likely) for a single application.

Templating options

Both Django and Rails template using embedded Python or Rails code (like using Java scriptlets in JSP pages). Much more work has been put into Rails’ helper code – Ruby code you can use to generate HTML constructs – its excellent Ajax support being one example. Django does make it fairly easy to swap in other templating options if required (such as Zope’s Template Attribute Language, or perhaps Clearsilver). I’m less savvy on alternate templating options available for Rails – although obviously if you used something else you’d have to do without many of the helper methods available.

Administration and User management

Django’s administration interface is simply excellent. Unlike Rails’ scaffolding views, it is not designed to be viewed by everyone (being an Admin console), but unlike the scaffolding it is perfectly functional and you could imagine making use of it without alteration in a production application.

The administration console is password protected – you can generate a superuser account using the command line admin script. Once you’ve logged in you can add more users and even groups – Django automatically generates permissions for both the admin functions and your models which can be assigned to a group.

You can also add new model instances in the same way as Rails scafolding, but the view is much better. You have nice popups and shortcuts for date and time fields, dropdown lists for one-to-many relationships, and multi-select lists for many-to-many relationships all provided without any developer interaction.

Rails does have a measure of user administration in the form of the add-on salted login hash generator, but despite some hard work by the developers it does seem problematic and nowhere near as slick as Django.

So which is right for you?

I said at the start that the two frameworks were developed as a result of two very different applications – and most of the differences between the two are a result of this. If you are developing a simple (in a domain model sense) application where you want to use Ajax to deliver a great UI, Rails is probably for you. If however you want to develop an entire site with different types of applications within it – then Django’s plugable applications and general approach might be what you’re after. Equally, the better user and administration side of Django favours portal style applications – this is something you’ll have to do yourself if you want to use Rails.

There is scope for both frameworks to learn from each other, and I still have a question around how well Rails will scale (in terms of the size of the site, not number of hits) – Django has already proved it is capable of this with LjWorld.com. Likewise it will be interesting to see if Django can or even wants to make the use of Ajax as simple as it is with Rails (although work is already progressing along these lines), or if the more powerful language features of Ruby will prove the deciding factor.

Personally, given my own current projects I’ll be spending some more time with Django – but all that means is that it is one more tool that will sit alongside Ruby, Rails and J2EE in my particular toolbox. And just like Java web frameworks before, I fully expect to see more and more web frameworks based on dynamic languages (such as Nitro or SeaSide) start to gain more visibility and yet more options. It seems we’re going to be spoilt for choice.

About these ads

61 Responses to “A comparison of Django with Rails”

  1. Disappointed

    [snip]If you are developing a simple (in a domain model sense) application where you want to use Ajax to deliver a great UI, Rails is probably for you.[/snip]

    Huh? So if I’m developing a complex (in a domain model sense) application, django is the way to go? You make this assertion, but offer nothing in the article to back it up. Are you spreading FUD or making a valid comment?

    Reply
  2. hugo

    Regarding FCGI and lighttpd: there are already descriptions online how to use django with FCGI and lighttpd and various other WSGI hosts (FCGI+Apache, Twisted, TooFPy) at the server arrangements page in the wiki.

    Reply
  3. Adrian Holovaty

    Thanks for the excellent, fair writeup.

    Clearly I’m biased, as I’m a Django developer, but I’d say Django is equally suited for “simple (in a domain model sense) applications” as it is for “an entire site with different types of applications within it.”

    For instance, I’m using Django to power chicagocrime.org, which is “simple” in that it’s a single application, and the system works equally well there as it does on Lawrence.com, which is *very* complex.

    Also, adding support for other databases in Django is as easy as adding a single Python module in a directory. (Granted, Oracle has some peculiarities that make it more complex than that, but other RDBMSes have fit into this quite nicely.) We’ll certainly be adding support for more databases as soon as we can.

    > The only minor annoyance is that there is
    > no equivalent of a model-specific SQL
    > refresh – something that could drop
    > a specific model’s tables and regenerate
    > the needed SQL automatically.

    For this, use “django-admin.py sqlreset [appname]“, and pipe that output into your database system, like so:

    django-admin.py sqlreset polls | psql myproject

    It’s intentional that there isn’t a command that does this automatically. My thinking was that Django *shouldn’t make it easy to delete data*. Adding something such as “django-admin.py reset [appname]” would be stupidly easy, but I’ve hesitated because I’m very protective of data. That said, we’re open to ideas on how to solve both problems.

    Thanks again.

    Adrian

    Reply
  4. biased to me

    Over the entire comparison I felt a spin in favor of Django, and it becomes a poor favor to it, ends up sounding like “don’t look at rails doooon’t.” maybe is just me but the frameworks appear to reflect the underlying language “way” and this leads to some of the framework’s approaches,lastly, no doubt Django will be able to retain many pythonists from goin Ruby, but I doubt it’ll atract Rubyists.

    yes I’m biased, but I think so are You.

    Reply
  5. Sam Newman

    Disappointed Wrote:

    bq. Huh? So if I’m developing a complex (in a domain model sense) application, django is the way to go? You make this assertion, but offer nothing in the article to back it up. Are you spreading FUD or making a valid comment?

    Well I do touch on this – management of your domain model is easier with Django as it doesn’t split up you domain model definition between code and DB schema like Ruby – therefore making it easier to manage. To be honest neither approach (Django or Rails) is going to manage a complex domain too well as the coupling to the DB is perhaps a little to tight.

    Reply
  6. chong

    One problem with Django is that it is more difficult to handle customization.

    For example, I released a hospital scheduling system to my customers.
    Some customers need to add a custom column
    to one of the form. With Rails, the customer
    can just add the column to the table (maybe
    start the column name with customer name), then the domain object will get it.

    I don’t know how this can be done in Django excpet to change the domain object which I think it is a bad idea since next time when I release the new version of my software, it will break.

    Reply
  7. Sam Newman

    biased wrote:

    bq. yes I’m biased, but I think so are You.

    Erm, not really. I say at the end:

    bq. Personally, given my own current projects I’ll be spending some more time with Django – but all that means is that it is one more tool that will sit alongside Ruby, Rails and J2EE in my particular toolbox.

    Meaning that it’s a classic case of right tool for the job. I think there are some things Rails is good at due to the place it came from (good UI, simple domain web applications) and some things django is good at (more passive UI, portal-type apps). I’ve actually spent more time working with Rails (at Ruby) as you’d know if you’d read much of the rest of my posts.

    This article was sent to both Django developers and Rails developers for feedback, and none of them complained of any apparent bias. The only bais that I have to Django right now is because the stuff I’m working on fits Django better than Rails.

    Reply
  8. Sam Newman

    Chong wrote:

    bq. With Rails, the customer
    can just add the column to the table (maybe
    start the column name with customer name), then the domain object will get it. I don’t know how this can be done in Django excpet to change the domain object which I think it is a bad idea since next time when I release the new version of my software, it will break.

    I’m not sure why it should be any different. If you add the column to the DB in Rails, unless you are using the scafolding you won’t get the view for free (e.g. the new field won’t appear on your forms unless you specifically code for it). I’d be suprised if _anyone_ would use the scaffolding view for a production application – it’s not really what they’re designed for.

    With Django, you’d have to change your domain model (which _is_ correct in my mind – if a domain model has a new attribute you need to change your code). Then you’ll have to migrate/refresh your DB schema. Then you’ll have to build your view code for the new field (assuming this field is visible to more than just the admin interface). With Rails the change is virtually the same – update the DB schema, migrate/refresh the DB, update the view.

    The difference is that with Rails you edit the DB schema by hand, in Django you edit the model file by hand and have it generate the schema. I prefer schema generation for reasons given above (and there is no reason why Rails can’t support it to, didn’t it used to?) – although once you have your DB in production every schema change needs to be carefully thought about.

    Reply
  9. ToddG

    I don’t think schema generation was or will be a part of Rails, it goes against DRY — at least that’s how I recall a discussion about it long ago on the list ending up.

    I think this split (diff approaches to model tier) might actually be a deciding factor for some people between the 2 frameworks, depending on if they’re mostly dealing with legacy DBs or can create their own Rails-ish ones, or vastly prefer one approach over the other.

    Reply
  10. Chris Esther

    I’m interested in your comments about Django’s ability to reverse-engineer models from existing schemata. What’s your source for this? I am keen to understand more.

    I would love to only deal with fresh green field developments but life’s not always like that…

    Reply
  11. Daniel Berger

    “On the other hand Python has a much cleaner syntax (which given its background is no surprise) – more than once I’ve found myself using a third type of parenthesis in the same Ruby method quite validly, only for me to look back at what I’ve done and feel that I’ve regressed to the bad old days of Perl.”

    I’m guessing that by “third type of parenthesis” you mean the different block syntax(?). Funny, most people seem to like Ruby’s block syntax. Or I’m missing something.

    As for cleaner syntax, well, I guess it depends on if you prefer a few ampersands or a lot of underscores. :)

    Dan

    Reply
  12. Will Gunadi

    This is one of the most objective review I’ve ever read. The author clearly is not talking out of the blue. He dissected the pros and cons appropriately.

    Heck, I even agree with most of his cons on Python (I just wish the link to the term “closure” is working because I’m itching to know what the author meant by Python not having as strong a language feature than Ruby. But this is minor because this language is not comparing Python and Ruby).

    To me, if RoR doesn’t offer the generated Admin web pages a’la Django (plus the user/group management to boot), then RoR is not for me (at least not for my current project). But I am *very* intrigued that RoR provides Ajax support.

    One thing about django, that users or potential users need to know especially if you guys are using Postgresql. Django produces SQL code that create tables that consumes OIDS.

    In most cases, this is not the desired effect because OIDS are unique per installation and *will* wrap around. Although django applications will not use these OIDS, every insert will unnecessarily consume an OID. Remember OIDS are used by Postgresql’s system tables (it still irks the heck out of me that they made WITH OID the default behavior with no way to change it).

    To counter this, I had to insert the string WITHOUT OIDS at the end of each CREATE TABLE.

    Reply
  13. Sam Newman

    Todd wrote:

    bq. I don’t think schema generation was or will be a part of Rails, it goes against DRY

    I’m not sure how this goes against DRY – the python model source is the single source of information for the domain model.

    Chris Esther wrote:

    bq. I’m interested in your comments about Django’s ability to reverse-engineer models from existing schemata. What’s your source for this?

    “Matt Croydon”:http://www.postneo.com/2005/08/05/migrating-your-app-to-django has a good overview on this. “Jacobs”:http://www.jacobian.org/2005/aug/16/django_and_rails/ post also touches on this.

    Michael Schubert wrote:

    bq. Rails does indeed support other caching backends

    Great links – thanks Michael. Anoyed Obie and Jon didn’t pick that up when they reviewed the article :-)

    Jondom wrote:

    bq. I fixed the link to closure.

    Fixed in the main article – thanks Jomdom and Dmitry for picking this up

    Reply
  14. Colin

    Both Django and Rails seem to be really nice framworks to develop with. And really a pleasure to use compared to the java MVC frameworks for which development time is skyhigh.

    At the moment Rails seems more mature in that it supports filters (like Servlet filters) and has a very easy way to make it impossible to not accept POST data to populate certain fields of an object. (For example if a User has the flag isAdmin, in Rails you could mark the Field isAdmin to be only settable through direct assignment, and not automagically populated by provided POST data)
    Django has the advantage that it is written in Python, for which alot more custom libraries are available.

    At the moment i prefer Rails, for the reasons mentioned above, plus DOCUMENTATION.. Django has decent documentation, bt Rails has a very nice book, explaining everything. This makes working with rails a lot easier compared to using Django, while i’m a ruby newbie, and have some expertise with python. Now i don’t need a book, but a complete manual for Django, with the explantaion of an example apllication would sure be nice)

    But as Django is under heavy development, and i’m sure they’re learning from Rails (and probably the other way around) I think in half a year from now both frameworks might share the same usefull (and less usefull) features (Or atleast the features i mentioned, maybe they’re even already there in Django, but undocumented as of yet)

    Reply
  15. Matt Revelle

    bq. I fixed the link to closure.

    This is slightly off-topic, but the mention of closures in this comparison led me to post an “invitation for practical closure examples”:http://mrevelle.blogspot.com/2005/08/closures-in-ruby-and-python.html and I mention a few links on the subject.

    I’m still looking for a practical closure examples that do something that “list comprehensions”:http://diveintopython.org/getting_to_know_python/mapping_lists.html can’t.

    Reply
  16. ToddG

    Sam, re: schema generation and DRY and Rails, as I mentioned, my recollection was hazy. Here’s the thread:

    Generating SQL from model and not vice versa
    http://article.gmane.org/gmane.comp.lang.ruby.rails/3606

    I guess it was sort of an inconclusive discussion… the general approach (model derived from DB) seems to have been what DHH found worked best in his experience. He mentions future code in that thread which became Migrations, which might be workable for this issue, I’m not sure: http://api.rubyonrails.com/classes/ActiveRecord/Migration.html

    Reply
  17. James Britt

    “I don’t think schema generation was or will be a part of Rails, it goes against DRY, at least that’s how I recall a discussion about it long ago on the list ending up.”

    Rails currently offers ‘migrations’, code that helps you create DB schema using Ruby. It is intended, I believe, mainly as a helper tool to get identical tables created across multiple databases.

    “Nitro”:http://www.nitrohq.com/ is another Ruby Web framework that, as with Django, derives the database schema from Ruby class definitions, an approach that is often a better mach for my deveopement style.

    There is work being done to allow mixing and matching of MVC libs from both Nitro and Rails, so people can have more options.

    Reply
  18. Sam Newman

    ToddG wrote:

    bq. Sam, re: schema generation and DRY and Rails, as I mentioned, my recollection was hazy. Here’s the thread:

    Thanks for that. Interesting that in that thread someone else claims it violates DRY, when in fact I think the reverse is true, especially if you need to support multiple DBs.

    James Britt wrote:

    bq. Nitro is another Ruby Web framework that, as with Django, derives the database schema from Ruby class definitions, an approach that is often a better mach for my deveopement style.

    Had a quick look at Nitro, but didn’t see that it also generated the DB schema.

    And thanks to both of you for the links to Migrations…

    Reply
  19. Aristotle Pagaltzis

    bq. Anyone having to consider which of the two frameworks is right for them is inevitably going to have to think about the task of hiring people and this may have an impact on their choice.

    I never understood why companies hire technologies instead of people. Certainly if I was a manager, I’d consider someone who has no experience with the tools the company uses but no problem picking them up within a short timeframe either to be more appealing than someone who has 10 years of experience with the tools in use but no capacity for picking up new ones.

    Hiring technologies is a fear-based strategy.

    bq. It would be nice to think that one day a language will come along which manages to add powerful features without making the code look like it’s been rendered with the wrong character encoding.

    Careful. You are asking for Lisp.

    Reply
  20. Sam Newman

    Aristotle Wrote:

    bq. I never understood why companies hire technologies instead of people.

    I agree, but it happens. It’s also important to note that development in dynamic languages probably requires a more mature development process than statically typed languages – if you want to tie yourself in knots, it’s _much_ easier to do it with a dynamic language like Ruby Python – so testing becomes more important. Put another way, if your developers have trouble writing easy to understand, clean maintainable statically typed Java/.NET code, don’t expect the situation to be any better with Python on Ruby – in fact I’d expect the reverse to be true!

    bq. Careful. You are asking for Lisp.

    I really hope that was a joke :-)

    Reply
  21. Aristotle Pagaltzis

    bq. if your developers have trouble writing easy to understand, clean maintainable statically typed Java/.NET code, don’t expect the situation to be any better with Python on Ruby

    That’s true — but if they’re _incapable_ of writing clean code rather than just not experienced enough to do so, you have more serious problems… And if they’re only inexperienced, you hopefully have a few senior developers to take them in for apprenticeship, or you’ll _still_ have more serious problems…

    Their code may not _look_ unreadable in Java, but it will still be incomprehensible and unmaintainable. You can’t abstract human understanding out of the process.

    Bottom line as I see it, hiring a technology, particularly the “industry standard,” is at best a recipe for languishing in mediocrity. It won’t make you sink, by any stretch, but it certainly won’t get you to any top either.

    bq. I really hope that was a joke :-)

    It was… _mostly_. :-)

    Reply
  22. Valentino Volonghi aka Dialtone

    > Ruby does seem to have some more powerful language
    > features – it has slightly better closure support than Python
    > (although perhaps not enough to be a differentiating factor)
    > and the extremely useful mixins. Ruby’s OO support also feels
    > much cleaner. Both support inheritance (Python supports
    > multiple inheritance, which Ruby’s mixins more than make up
    > for).

    This whole paragraph is completely useless and very poor on details to the point of being misleading and clearly wrong.
    A closure is just a function that has access to the enclosing namespace. There’s no way you can have more powerful or less powerful ones. If you refer to being able to pass a block/lambda to a function or stuff like this you are clearly wrong. While functions/methods in ruby are not first class citizens they are in python. This loosens quite a lot the need for anonymous blocks since you can easily use named functions passed.

    I can’t get how python is missing mixins. Do we all agree on what a mixin is?
    The real thing is Ruby that lacks multiple inheritance (that permits all the mixins you might ever need and even more) and replaced this lack with “mixin”s.

    And I would also like to know how ruby object oriented support is cleaner. Everything is an object in python, you can do whatever you want with anything (also subclassing builtin types directly).

    Really… It is not like that these 2 languages are any different in terms of potential.

    You could have talked about the fact that ruby allows you to change the behaviour of built-in types, while python doesn’t. That ruby has a full implementation of blocks, while python has a limited (intentionally) implementation of lambdas and many other differences, but you didn’t.

    BTW: my aim is not to start a flamewar. I’m just fed up with people repeating this stuff each day… Can’t you just avoid comparing python and ruby? They are pretty much equivalent as you state as well.

    Reply
  23. Sam Newman

    Valentino wrote:

    bq. A closure is just a function that has access to the enclosing namespace. There’s no way you can have more powerful or less powerful ones

    I have clearly over simplified. Here is some constructive feedback I was given on this very point (although not on this blog):

    bq. Python does have support for full closures (see Ivan Moore’s articles here: http://ivan.truemesh.com/archives/000392.html and here: http://ivan.truemesh.com/archives/000411.html ) but it has broken lambdas which can only be used for expressions and can’t contain a return. As Ivan points out in the second of the articles I mentioned you can get around this by defining a function inline and using that. But it’s not as neat as the usual one-line examples of closures that everybody else uses. It’s one of the reasons why I’d like to see lambdas either fixed or removed.

    bq. The real thing is Ruby that lacks multiple inheritance (that permits all the mixins you might ever need and even more) and replaced this lack with mixin’s.

    So you claim that multiple-inheritence is _more_ powerful than mixins. I disagree. On balance, I actually disagree with my point about mixins being _more_ powerful than multiple-inheritence. Functionlly, they are two different ways of accomplishing the same thing. I prefer mixin’s because (to quote the “c2wiki”:http://c2.com/cgi/wiki?MixIn) “no semantics will be implied about the child “being a kind of” the parent”. Of interest, what can you do with multiple inheritence that can’t be done with mixins?

    bq. And I would also like to know how ruby object oriented support is cleaner.

    Err – can you name another language which claims to be OO and then requires you to pass @self@ in everywhere? OO was an afterthought with Python. Clearly it hasn’t been tacked on as badly as in Perl, but in a language which so badly wants to be seen as being cruft free with a nice syntax, this sticks out like a sore thumb. That and the underscores.

    I find it interesting that you comment on a single part of the fuller article, of which I myself said:

    bq. Ultimately comparing two languages that are so close (they’re certainly more similar to each other than Java or .NET) is going to come down to personal choice or a specific requirement. But for more indepth comparisons you’ll no doubt find many out there on the web.

    Do you have any comments on the rest of the piece? I’m all for constructive criticism – that’s why these comments are here.

    Reply
  24. Valentino Volonghi aka Dialtone

    > I have clearly over simplified. Here is some constructive
    > feedback I was given on this very point (although not on
    > this blog):
    [snip]
    > But it’s not as neat as the usual one-line examples of
    > closures that everybody else uses. It’s one of the reasons
    > why I’d like to see lambdas either fixed or removed.

    This is exactly what’s wrong in what you said. The concept of closures has NOTHING to do with lambdas and anonymous functions.

    A closure is a function (named or not) that has access to the enclosing namespace.
    lambdas, blocks or whatever are functions that can be used to define closures.
    The capability of defining closures using lambdas or anonymous blocks or ‘named’ functions is completely unrelated to the powerfulness of closures implementation.
    Actually the overhead of creating a ‘named’ function (I say ‘named’ because the name is actually _ [underscore]) in python instead of using a lambda/block is 1 line.
    Stating that one implementation is less powerful than the other because you need one more line is, at least, misleading.

    > So you claim that multiple-inheritence is more powerful
    > than mixins. I disagree. On balance, I actually disagree
    > with my point about mixins being more powerful than
    > multiple-inheritence. Functionlly, they are two different
    > ways of accomplishing the same thing. I prefer mixin’s
    > because (to quote the c2wiki) “no semantics will be
    > implied about the child “being a kind ofâ€? the parentâ€?. Of
    > interest, what can you do with multiple inheritence that
    > can’t be done with mixins?

    Being is-a Plane and Toy is actually a feature that you get for free with multiple inheritance that you are not forced to use if you don’t need. But yes, they are functionally equivalent, yet python doesn’t force multiple inheritance upon you and you can easily provide an alternative algorithm (in 5 lines or so) to use composition.

    > Err – can you name another language which claims to
    > be OO and then requires you to pass self in everywhere?

    How does this makes ruby OO implementation cleaner? I would say the opposite. Python implementation of this particular aspect is cleaner. Because self is not always the instance, it might be the class or the metaclass or, if you are in a static method, it wouldn’t exist.

    Apart from this:
    The word cleaner means that there’s something wrong with the python implementation (not just that you don’t like the API but that there’s some incoherence in it and I can’t really see it).

    > OO was an afterthought with Python.

    In what way? We are talking about recent versions of python (> 2.2 which is 5 years old more or less and all the production code out there is mostly written in this version)

    > Clearly it hasn’t been tacked on as badly as in Perl, but
    > in a language which so badly wants to be seen as being
    > cruft free with a nice syntax, this sticks out like a sore
    > thumb. That and the underscores.

    You seem quite a bit confused on this stuff. Underscores are a symptom of being an afterthought?

    > I find it interesting that you comment on a single part of
    > the fuller article, of which I myself said:

    Why should I comment on something that I agree with? That is what I’ve been saying since the beginning of my answer. But I have never said anything about ruby being slightly more broken than python because it isn’t true (and neither is the opposite).

    Reply
  25. Daniel Schildt

    Nice article. I have been interested of RoR for some time and recently found information about Django. Both look promising but I’m not sure which way to take. I have no previous programming experience so question is more like what would be better for beginner.

    In general, it looks like Python much larger number of users and that also means there should be more documentation (about programming language). My concern with Ruby is that if there is enough (English) documentation but looks like it’s improving fast when more and more users start using it.

    And back to the main subject of article, currently Rails really has much better documentation. But that of Django is probably going to get better in time. Anyway, there is room for both in the world.

    Reply
  26. Per Wigren

    Regarding Rails schema generation.

    Rails has a feature called “Migrations”:1 which is a powerful tool to keep several databases up-to-date. It will give each DB a version number so a simple “rake migrate” will run all migrations left to make the DB the latest version. Migrations are run inside a transaction so if a migration fails it will rollback, giving you a chance to fix it.

    A common use for migrations is to have the first version create the whole initial DB-structure so running “rake migrate” on an empty DB will give you a fresh up-to-date DB.

    [1]http://rails.rubyonrails.org/classes/ActiveRecord/Migration.html

    Reply
  27. The Badger

    Sam Newman: “Err – can you name another language which claims to be OO and then requires you to pass self in everywhere?”

    The Modula family of languages also have the notion of self parameters. But then objection to such things as if advocating some kind of notion of “OO purity” is a phenomenon we’ve come to expect from adherents of the Perl family of languages and, of course, the Ruby peanut gallery.

    It’s a shame that you’ve chosen to undermine an otherwise informative article with such flawed observations.

    Reply
  28. Matthias Urlichs

    Since when do you need to “pass in” ‘self’ in Python? You don’t — you simply call the (bound) method.

    The only thing you _do_ is to explicitly _name_ the ‘self’ parameter – if you want to call it “foo” because your method actually gets a ‘self’ from somewhere else which it then uses, that’s perfectly valid.

    Of course, if you have an unbound method, you do pass ‘self’ as the first parameter, but that’s hardly unusual — the method must get its object from *somewhere*.

    Reply
  29. Sam Newman

    Matthias Wrote:

    > Of course, if you have an unbound method, you
    > do pass ‘self’ as the first parameter, but
    > that’s hardly unusual – the method must get
    > its object from somewhere.

    But Python is the only language which calls itself OO which has these sorts of issues, all because OO was factored in after the original language was created. In Java there is no need to talk about self (well, ‘this’) as Java knows that all instance methods have a ‘this’, and that static methods don’t.

    It may seem simply to be an added convenience to some, but when moving from other languages which have cleaner OO implementations it can grate a little.

    Reply
  30. João Marcus

    Could you *PLEASE* tell me what is *SO* wrong about the Python self thing? I thought it was strange, but I decided to try Python and I realized I was not annoyed about it at all. One thing that turns me down about RoR is the )(*@!# arrogant “Ruby is the best and Python and Java and anything else sucks” attitude.

    Reply
  31. Sam Newman

    First off, *it’s annoying*. I don’t have to do it in any other OO language, why Python? Sure, other languages have their quirks and annoyances – I’ve mentioned Ruby’s occasional syntax in the article above – self just happens to be one of Pythons.

    As for thinking I’m an arrogant Rails fanboy, you obviously didn’t read the whole article, or anything else I’ve written if you think that :-)

    Reply
  32. Julik

    A wonderful flamefest you got here if you ask me.
    I think you should mention one more thing which makes Django special in one very specific way. It has a notion of “meta” – that is, information about the object which is used, for example, for forms. This is something which is not really MVC-like but it works rather well,and Rails doesn’t have this (there is no way to quickly describe a form with a DSL along with all relationships). Granted, it has form helpers but they are nowhere near Django’t meta automagic.

    But in general you are right – Django seems to have emerged from the need to rig up portal sites quickly and incrementally, Rails is more fit for an application without the dreaded “/admin” url and iterative development. I still love Ruby more as a language though. What I would really love to have would be Rails with some pieces of Django :-) I hope that will come once. The notion of mediators is nice.

    And – what is important for me – I see many non-English names on the Django mailing lists and I see that i18n and l10n actually are core features and are being taken care of. This is what I would love to see in Rails ASAP (and it’s coming).

    Reply
  33. thakadu

    As regards the use of “self” in python methods, I know this is personal taste but I really like having to use it. It makes reading other peoples code much easier because it is very clear when a variable being referred to is a class variable and when not. For example, in java code, when working in a team I always recommend the use of the “this” qualifyer as it makes the code clearer. Python just enforces the use of it. I think the complaints were more about the inclusion of “self” as an argument in method declarations, and again I believe it makes clearer which functions are true methods and which are just static functions. In java you would use the “static” keyword which is 2 more characters :)

    Reply
  34. Sam Newman

    Ah yes, but most OO Java code has few class methods, so you don’t find yourself using static that much as a method-level keyword :-)

    Reply
  35. foobarbaz

    Jeebus, it could be worse. You could be stuck in JavaScript, where you never know exactly what “this” refers to!

    I love Python and the “self” doesn’t bother me. I haven’t played with Ruby but it looks like a slightly more cluttered version of Python.

    Reply
  36. Alain O'Dea

    Here’s a techical nitpick about this page itself: some of the characters are not displaying correctly on Windows XP Pro. Firefox 1.0.7 displays them as black diamonds with question marks in them and Internet Explorer 6.0.2900 displays them just as question marks.

    The character set of this page is not UTF-8. It appears to contain MacRoman characters. They appear to be intended to appear as apostrophes (should be ') and em dashes (should be —). This is likely the fault of your blog client software. If the encoding is set to MacRoman on the page, most browsers should render it properly. Better yet your client software should send the valid UTF-8 characters and HTML entities as necessary.

    http://validator.w3.org/check?uri=http%3A%2F%2Fwww.magpiebrain.com%2Fblog%2F2005%2F08%2F14%2Fa-comparison-of-django-with-rails%2F

    Reply
  37. sam

    dag nabbit – when I switched over to wordpress I didn’t check the character encoding. I can sort that easily enough when I have a spare ten minutes

    Reply
  38. Matt Boersma

    I like python’s use of “self.” It effectively tags methods as bound or not and makes the OO machinery more plain.

    Python could simply pass in a self parameter silently and have it always be available within the method–apparently that would silence Ruby users’ complaints. But “magic” like that is syntactic sugar that python has always worked hard to avoid–witness the grudging inclusion of a ternary logic operator in 2.5.

    On a related note, the Django 0.95 “post-magic-removal” code is superb. It wasn’t hard to port my old code, and the changes were all good.

    Reply
  39. Jim Kleckner

    I agree that the explicit nature of declaring “self” is desirable.

    Code is read more times than it is written and the more explicit things are the better, even for the author. When you invoke a method on an object, the syntax doesn’t require an extra argument – the variable provides it. The regularity of syntax to invoke methods on the instance using the self variable is a big improvement. It removes confusion about whether this is a global function or a method.

    One of the big challenges in a large C++ project is knowing “what is going to happen, exactly, when I invoke this operator?” C++ takes to the extreme the ability to indirectly override behaviors at any level of inheritance. You end up having know everything.

    Reply
  40. katalog

    Jeebus, it could be worse. You could be stuck in JavaScript, where you never know exactly what “this” refers to!

    I love Python and the “self” doesn’t bother me. I haven’t played with Ruby but it looks like a slightly more cluttered version of Python.

    Reply
  41. Rodney Hawkins

    Excellent post. I’ve been using Rails for a month now but switching to Django as I find it so much more powerful since their is so much extra support offered. Django is clearly the way forward for me and especially since Python is migrating much faster to the more powerful x64 architecture. Python also is much closer to Java than to Ruby and for me, a Java Servlets oke, this is the weapon of choice. Thanks! :)

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: