Recently there has been a spat of Ruby VS Python threads, both in ruby-talk
and in comp.lang.python. I don’t recommend reading the threads, they
are repetive, filled with misunderstandings (from both sides) and more
personal attacks than technical content.
However, one thing I have noticed is that Rubyists and Pythonistas bring
different assumptions to the table. What is intuitive to one group seems ad
hoc and downright weird to the other.
Here’s one example that I noticed.
In Python, the construct "x.y" means lookup the name
"y" in the dictionary of "x". (Ok, that’s
simplified, but you get the picture). The result of that lookup may be a
value (instance data), or may be a function that can be called (member
functions). In other words, "." is basically a lookup operation.
In Ruby, the construct "x.y" means send a message named
"y" to the object represented by "x". All operations on
an object must be done through the sending of a message.
This leads to all kinds of non-intuitive behavior if you are expecting the
wrong thing. For example, one Pythonista commenting on the fact that
"x.y" and "x.y()" are equivalent asks the question:
"How do you get access to the y function inside x?".
A Rubyist’s response to the question is "Huh?". You see,
there are no "functions" in Ruby. At least not in the way the
question assumes. Ruby’s unit of execution is a method, and methods
are not first class objects in Ruby. If you wish to have a callable object
that references a method on a particular object, then that is easily
accomplished by asking the object for a Method object.
o = Object.new
m = o.method(:to_s)
m.class # => Method
Note the difference between a method (an internal Ruby construct) and a
Method object (an object that represents the internal method bound to an
instance). To "call" a method object (or any callable object in
Ruby), you send the object the "call" message. So, the result of
calling m should be identical to the result of sending to_s to o directly.
And we see that it is.
Although Python and Ruby are similar in many ways, their basis for
computation is quite different in some fundamental ways. Python follows C++
and Java in using "." as a structure selector operation, while
Ruby is more closely attuned to Smalltalk’s message sending paradigm.
Both approaches work and are interally consistent, but be prepared for
surprises if you try to interpret one using the assumptions of the other.