where I compare Python & Ruby

Oh, another Ruby vs. Python post?

you

No. Actually, I don’t want to say that one is better than the other one, I just want to share awesome and awful moments with both of these languages. And by “languages” I mean not just the syntax and the standard library, but also the community, libraries, etc.

Awesome moments

Ruby Blocks

Ruby blocks are super cool. Not just for DSLs, but also for working with data and stuff.

articles = Nesta::Page.find_articles.reverse
idx = articles.find_index { |e| e == page }

Python List Comprehensions

These are better for functional programming.

ids = [entry["id"] for entry in db[skip:][:limit] if matches(entry, query)]

This was just map and filter, with readable syntax.

Ruby Benchmarking

It’s right there in the standard library! Add this to .irbrc:

def bm(repetitions=100, &block)
  require 'benchmark'
  Benchmark.bmbm do |b|
    b.report {repetitions.times &block}
  end
  nil
end

Python Types

I’m working on a web toolkit called RapidMachine. With it, routes look like this:

class MyApp(App):
    handlers = [
        Route('posts', Var('name')).to(PostResource),
        Route('comments', Var('id', int)).to(CommentResource)
    ]

Noticed that “int” thing in the second route? Yes, I pass the int type to Var, which is just this:

class Var(object):
    def __init__(self, name, typey=str):
        assert type(typey) == type
        self.name = name
        self.typey = typey

And the request handler just converts the value from the requested URL to the type (in this case, int). /comments/123 matches and the parameter is 123 (an int), /comments/hello returns Bad Request.

Ruby REPL awesomeness

Wirble, Sketches, Hirb and all that stuff.

Python Namespaces and Imports

Namespaces are one honking great idea – let’s do more of those!

Tim Peters, The Zen of Python

Ruby frameworks (and by that I mean Rails) like to do that magic when you just write your classes and stuff in files and everything is available from everywhere. Nice to write, not nice to read. When you look at a Python source file, you see where things come from.

from datetime import datetime
from somewhere.coolapp.utils import slugify

def prepare_post(post):
    post.text = slugify(post.text)
    post.date = datetime.now()

In a Rails app, I’d have to search for that slugify function throughout the whole codebase and in all the gems the app depends on.

Don’t forget that namespaces allow you to avoid things like:

MyApp::Utils::Parser.new(text, MyApp::Utils::SAFE)

Even if you have your own constant for marking things as safe, you’ll be just fine:

from myapp.utils import parser
from myapp.utils import SAFE as MYAPP_SAFE

parser(text, MYAPP_SAFE)

Awful moments

Ruby Blocks, again

Ruby block syntax is confusing. do/end or curly braces? Some people have conventions like curly braces for short and/or purely functional things, do/end for things with side effects, etc. But sometimes one syntax works and the other one doesn’t. I don’t know why, for example, this works:

haml_tag :a, :href => prev_a.abspath, :rel => 'prev' do haml_concat '← previous post' end if prev_a

but this doesn’t:

haml_tag :a, :href => prev_a.abspath, :rel => 'prev' { haml_concat '← previous post' } if prev_a

“syntax error, unexpected ‘{’, expecting keyword_end” – what?!

Python 3

It breaks too much stuff. Most library developers can’t afford supporting it (for now).

Ruby Community

That brogramming thing started with Rails people, right? The infamous CouchDB talk happened at a Ruby conference.

I know there are a lot of good people in the Ruby community. No, that doesn’t help, because the author of Rails calls himself an R-rated individual and an RSpec core team member says things like “Can’t we all just agree that woman don’t want to program?”, then uses Derailing for Dummies as his handbook: “I Know Another Person From Your Group Who Disagrees”, the father thing, good old “joke” thing.

This is why we can’t have nice things.