where I compare Python & Ruby
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
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.