In regards to Ruby and Python Compared:
Larry Wall, the designer of Perl, has the slogan "There's more
than one way to do it". In contrast, Bertrand Meyer, the designer
of Eiffel, says "A programming language should provide one good
way of performing any operation of interest; it should avoid
providing two." Ruby follows the anarchist approach of Larry Wall,
while Python follows the bondage-and- discipline approach of
Eiffel.
Python is not in any way a B&D language. At all. Even slightly. No
resemblence. It takes nothing from Eiffel. It probably could take
some good ideas, but right now it doesn't even take any of its good
ideas.
Python attempts to build consistency with a carrot approach, not a
stick. I say "attempts" because there are many places where the
Python community doesn't agree on a solution, doesn't agree on the
phrasing of the problem, or simply doesn't know the best way to do
things. There will always be such places, until such time as all
programming problems are solved. Despite the futility of this effort,
we still pursue compelling, complete, and consistent solutions.
An important rule in the Python community is: we are all consenting adults. That is,
it is not the responsibility of the language designer or library author
to keep people from doing bad things. It is their responsibility to prevent
people doing bad things accidentally. But if you really want to do something
bad, who are we to say you are wrong? It's your program. Maybe you even have
a good reason.
That said, it's unlikely you'll see language designers or library authors going
out of their way to enable you to do bad things where it was previously
impossible. So some feature suggestions that are likely to cause errors are
unlikely to get much consideration.
Python usually seems to have one best way to perform a given task,
and even prescribes how the code is to be laid out, since
indentation is syntactically significant.
Of course you'd have to be nutty not to indent your code the way
Python wants you to. Python is DRY (Don't Repeat Yourself) here.
Ruby's treatment of Booleans is much cleaner. In ruby, false and
nil are considered false in boolean contexts, and everything else
is considered true. Python follows the antimathematical convention
of C and Perl where 0 is considered false. This nonsense really
has no place in such a high-level language. But Python makes
things worse: empty lists, empty dictionaries, and empty tuples
are false. What about empty sets? Well, sets are not a built-in
type, so it depends on how they are implemented. Python lacks true
booleans: true and false.
I don't think this is a very meaningful comparison. If you want to
test for nil/None, test for nil/None. I guess you could say that Ruby
is like Scheme or Smalltalk, and Python more like Lisp. There's points
for and against each technique, but smart people have and continue to go
both ways; just get used to it.
That False == 0 and True == 1 is an artifact of a time when
Python lacked true booleans (though now True and False are
"true" booleans, even if they are also integers: False is not 0). While the
underlying integer nature of True and False lacks elegance, I haven't
had any problems with it in practice.
As for other things being false (I use a lower-case "false" to refer
to all falsish items in Python), this is just how Python is.
Falseness is a property of an object. Empty sets are false, because
thats how they are implemented. Convention, not the language,
enforces the greater concept of what is "false".
In C, 7/3 is 2. I'm really a mathematician rather than a
programmer, so I feel that 7/3 should be the rational number
7/3. The earlier versions of Python followed the C
convention. Happily, Python has finally switched. Ruby defaults to
the C convention but also gives the ordinary convention for
rationals when you require the mathn standard library. I always
require the mathn standard library!
In Python 7/3 is still 2. It probably will be until Python
3.0; Guido regrets the original decision, but changing it before 3.0
is way too big a problem. This isn't a reflection of some deep design
principle in the language.
Python does not allow a library to change what 7/3 evaluates to.
Here Python the language is taking over, where in Ruby a library can
effect this. I assume in Ruby that means -- when the mathn
library is loaded -- that division of all integers produces rationals...?
But that seems so incredibly broken that I must assume it is not so.
Python's OO has become more extensive in recent versions, but it
is still an OO bolt-on to a procedural language. Ruby is
thoroughly OO. In Python, it is rather arbitrary whether some
functionality is implemented by a function or a method (which have
different syntaxes), and the programmer just has to remember how
Python does it. Python has types and classes; in Ruby types are
classes.
It's not "arbitrary," it's an aspect of whatever thing you are using.
Not all libraries are designed the same, not all libraries are well
designed, so sometimes a method is chosen when a function would do, or
vice versa. You can make the same choices in Ruby. As a convention
people in Ruby use methods far more often. Over time I personally
have come to use functions more often than methods, only using methods
if I see that a compelling object has emerged in my code. This is a
difference of opinion. But Python isn't the only place where people
are starting to feel more disaffected with class-based OO, though
really it's an aside to the particulars of the language.
The distinction between classes (read: old-style classes) and types
(read: built-in types, types written in C, new-style classes) is
subtle and related to legacy. The distinction should disappear in
3.0, and you can mostly ignore it in current versions as well.
Until recently, Python's multiple inheritance had a critical
design flaw which made it useless except as a way of implementing
mixins. Whether the improved multiple inheritance will buy Python
anything besides confusion has yet to be seen.
If it doesn't work for you, don't use it. In practice very few people
use multiple inheritance anyway. Whatever.
But Ruby's thorough, dynamic OO gives the programmer incredible
power. Methods can be easily added or removed from classes at
run-time. They can easily added or removed from individual
objects!
This can be done in Python as well, though it does not have the
syntactic support that Ruby has. Some Python classes, including many
built-in classes, are not possible to extend. Extending core classes
is a highly questionable practice in my mind -- useful for clever
hacks, but not for serious programming.
There is direct support for popular design patterns such as
"Observer", "Delegator", "Singleton", "Visitor".
This is true; Python does not have any specific culture around these
patterns. Though some patterns like "Singleton" are total nonsense
anyway. But then, I don't really know what the support in Ruby looks
like, so I don't know how I'd recognize it in Python.
A Ruby program has great capacity for "reflection", the ability to
observe itself. Want a list of all living objects belonging to a
particular class? No problem! Should you enjoy life in the fast
lane, a ruby program can effectively rewrite itself at run-time.
Python's reflection is quite good. The list of all living objects,
however, does not exist.
Python's garbage collection is based on reference-
counting. Ruby's is mark-and-sweep (scheduled to be replaced by a
generation-based system). Python's system allows the programmer
more direct control over garbage collection: the del operator
tells Python to garbage-collect a specific object right now. But
Python's reference-counting system can easily lead to memory
leaks, especially when trying to interface with C-code. Little
rings of co-referential dead objects can accumulate with a
long-running Python program.
This is not true.
Ruby is capable of Perl-like one-liners that can be used on the
command line for system administration. Python is unsuitable for
this.
Hey, one liners work in Python too. Generally speaking, Python is
a very popular system administration language; certainly Perl is still
king, but at least in the Linux world Python is the clear
up-and-coming system administration language.