More Ruby vs Python

Following the post of MacSlow:

Mark Ramm says:

Felepe, have you looked at ctypes? I think it makes writing c extensions for python awfully easy. I like both Ruby and Python, but it seems the Ruby people are always running around pointing at flaws in python that don’t really exist.

First of all, its Felipe.

Doesn’t really exist? Please read this post where I explain a lot of the things I don’t like.

The thing that I dislike the most is the hash table behavior:

foo = {}
print foo[”bar”]

Returning Null makes much more sense than raising an exception, it makes coding so much easier. In my opinion this is a huge issue, I _always_ have to check _if_ the key is present then put the value, if not then put null.

In C with GLib it’s even easier than with Python!

Python’s ctypes look good, but that has nothing to do with the bridge between Python and C. That is what I’m talking about.

If I like C and I want to write Ruby extensions in C, I want that to be simple. I want to use Makefiles, pkg-config, everything as I’m used to.

So ctypes is another way of doing things, but it’s a way I simply don’t want to follow.

The two languages have made different choices, and perhaps Python’s pragmatism beats purity philosophy means that Python isn’t always as pretty as Ruby. But when it comes down to daily work I get things done in python more quicly than in Ruby. This isn’t an objective judgment. I know I’m faster at Python because I know Python better, because the libraries are more mature, and because Python just fits my into brain easier. For example, Python lists are much simpler than Ruby arrays (python lists have 9 methods vs Ruby’s 80+), yet I can still do all the same stuff.

Yes, I do things faster in Ruby. The libraries are not that mature, but are much more intuitive to me. For example Python’s urllib2 is ugly as hell compared to Ruby’s Net::HTTP.

Python:
import urllib2
theurl = 'foobar.org'
protocol = 'http://'
username = 'foo'
password = 'bar'
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, theurl, username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)
pagehandle = urllib2.urlopen(protocol + theurl)

Ruby:
require 'net/http'
url = URI.parse("http://foobar.org")
req = Net::HTTP::Get.new(url.request_uri)
req.basic_auth("foo", "bar')
http = Net::HTTP.new(url.host, url.port)
res = http.request(req)

How could Python’s approach could fit anyone’s mind better than Ruby?

I think less stuff to remember for the same feature set makes python easier to learn.

You need to remember exactly the same stuff in Ruby than in Python. The fact the you have more options doesn’t mean that you need to learn them in order to use arrays.

For me this makes much more sense:
array.join("?")

Than:
"?".join(array)

I like Ruby’s blocks, and I think some parts of Ruby are definitely prettier than Python. But I’m tired of Ruby advocates’ dismissive attitude, and failure to actually do their research into the best ways to do things in Python. Too many people criticize Python for things that haven’t been true for years — such as the “ugly” the C extension mechanism (hasn’t been true since C Types) or the “type class distinction” (hasn’t been true since python 2.2).

I think I have spent a lot of time searching for the Right Way to things in Python, I just plainly don’t like it.

I can’t recall any code where I prefer Python’s version over Ruby’s.

Sure, there are performance issues and the maturity of libraries is not as good as in Python, but those will only improve. The language itself is mostly going to stay the same (beautiful) and Python will not get that better.

20 thoughts on “More Ruby vs Python

  1. The hash table behavior you want looks like this in Python, just FYI:

    >>> foo = {}
    >>> print foo(”bar”, None)
    None

  2. twill is much simpler than mechanize in python. With twill your example would look like this:

    from twill.commands import go, show, add_auth

    URL=”http://foobar.org”
    # Adds authentication information for all sites in the domain URL
    add_auth(url, "foo", "bar")

    #Navigates to URL
    go(URL)

    So, sure mechanize is more verbose than Net::HTTP, but twill is much nicer than either of the two.

    So I stand by my claim, there are a large number of Ruby who people consistently provide python examples that are uglier than they should be, because they want to make a point about the “prettiness of Ruby.”

    And you seem to be missing my other point too. It’s not writing code that requires knowing the 80+ methods on the Array class, it’s reading other people’s code. And I think it’s a well known fact that more time is spent maintaining and extending existing code than writing new code. So, in that case I think Python makes the right choice.

  3. I get this:
    NameError: undefined local variable or method `twill' for main:Object

    So I suppose it’s not the official Net library. So in fact what you are saying is that if I want a simple API I basically shouldn’t use Python’s official API. The point was not weather or not there are cleaner alternatives (Everyone can make a twill implementation in Ruby too), the point is that the recommended API for that case is much more difficult in Pyton than in Ruby.

    I did not choose that particular example, it’s simply something that I need, and when I search in Google about how to do that the best possible way, that’s the answer I get, and I cannot find a simpler one. And BTW, I don’t want to install twill just for basic auth, nor I want my users to do that either, it’s so simple I can do it by hand, but that’s not the “recommended” way to do that.

    And about the Array class thing: it’s not really a problem. From my experience no one really reads the whole language documentation before starting to read code. Everyone has it’s own way to learn/read code of a particular language, but usually it includes reading the documentation when in doubt. From what I can see pretty much all the functions in the Array class are easy to understand without looking on the documentation.

    So your assumption that less functions in the Array class makes the code more easy to understand is flawed IMHO. I think there are a lot of things to consider, and I already provided an example where I clearly show that the Array function “join” actually makes the code more readable/understandable, at least to me.

  4. Pingback: synergy of loxal Archive » Ruby vs Python concept from a philosophical point of view

  5. FUD


    print foo.get("bar", None)

    and your Python example was extremely contrived.


    from urllib2 import build_opener, HTTPBasicAuthHandler
    auth = HTTPBasicAuthHandler()
    auth.add_password(None, "foobar.org", "foo", "bar")
    opener = build_opener(auth)
    opener.open("http://foobar.org")

  6. To get null on a simple hash access in Ruby (any depth), you can just do:

    blah = {}
    result = blah[‘key’] rescue nil

    even this works:

    blah = {}
    result = blah[‘one’][‘key’][‘really’][‘deep’] rescue nil

  7. Boy, do you like taking the long way ’round for your Python examples.
    It takes two lines to get the contents of a passworded web page:

    from urllib import urlopen
    content = urlopen(‘http://user:password@example.org/’).read()

    [admittedly, urlib vs. urlib2 is a mess, but fixed in 3.0]

    As for array references with an invalid index returning Null, that
    really only makes sense if you don’t have a good exception
    mechanism. Otherwise, how do you tell the difference between a missing
    index and and a stored Null value? I suspect I’d wind up writing the
    equivalent of:

    val = arr[ind]
    if val is None:
    raise IndexError(ind)

    All the time in Ruby, because trying to retrieve values that haven’t
    been stored is normally an error in my code, so my habits would clash
    with the language. You’ve seen this in reverse, but incorrectly
    assumed the fault was with the language.

    Personally, I gave up on Ruby when I found out that you pretty much
    can’t do functional programming in it. If I can’t pass a function as
    an argument in a language, using it is going to be a major PITA for
    me.

    <mike

  8. Mike: when I wrote this Python 3.0 wasn’t nowhere to be seen.

    This is what you do in Ruby if you want to throw an exception:

    arr.fetch(index)

    Or you can override the Array class:
    class Array
    alias [] fetch
    end

    I don’t think it’s purely a matter of custom, returning nil allows much simpler code. Exceptions are good, but enforced exception handling isn’t, should be optional, like in Ruby: you have functions that throw exceptions, and functions that don’t.

    Can’t pass a function as an argument? What are you talking about?
    def run_func(func)
    func.call("hello world")
    end

    run_func(lambda { |arg| puts arg })

  9. Okay so you hate everything in python and say that ruby is the best. But you always forget to look at efficiency😦
    Every time you say something bad about python it’s related ONLY to the syntax. It’s ugly / longer / less readable… So you’re right. that’s the only advantage of ruby over python🙂
    Python is much more functional and efficient. It focuses you on functionality which makes developing faster and easier. And that advantage of python over ruby… kills ruby.

  10. @Shmuel If I want efficiency, I use C, not Python.

    If I want a mix between efficiency and convenience, I use a mixture of C and Ruby. In fact, coding Ruby in C is so easy, that it’s similar to C library helpers, such as GLib. But I would like to see one exactly of a piece of code that “kills” the performance in Ruby, but not Python.

  11. Python has more efficiency than C. But it’s slower…
    Okay so lets look at the world out there, which language produced more successful applications?
    Here is just a small taste of python’s power:
    http://en.wikipedia.org/wiki/Comparison_of_BitTorrent_clients#Interface_and_programming

    This is just an example of how python is super efficient compared to ruby.
    Almost 9 BitTorrent clients written in python, and 0 in ruby.
    (in fact I almost never heard of a good, or atleast known software written in ruby)

  12. I think what shmuel meant was that Python is a more productive language than C, but runs slower. But then, Ruby is just as productive as Python, if not more. In fact, the two languages are almost identical twins, except that Ruby has better designed syntax but is less known. I don’t get where he got the Python is more productive than Ruby idea.

  13. I stopped reading at “returning nil [when accessing an array element under a non-existing key] makes much more sense”. That statement speaks volumes of either inexperience with any large scale programming, an absolute lack of sense of software quality, or simply someone whose strengths are clearly in fields other than programming. But it’s the Internet. Everybody with a keyboard is allowed to have a public opinion on anything…😐

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