Francis Avila:
Ruby uses messages to methods (which attached to
objects), and methods themselves are not first-class, so there's no
ambiguity.
http://onestepback.org/index.cgi/Tech/Ruby/PythonAndRuby.rdoc
I can't understand the syntax in the example code that shows how you'd get a
Method object.
I was thinking of how to elaborate on the description on that page, but
all I could come up with was basically a restatement. I'll give it a go
anyway.
In Ruby, the line
obj.methname(param1, param2)
is the same as
"send the message 'methname' with parameters 'param1' and 'param2'
to 'obj'"
In Python it is the same as
"get the method named 'methname' from 'obj' then call it with
parameters 'param1' and 'param2'"
In Ruby it's a one step process. In Python it's two steps.
In Ruby, the line
obj.methname
is the same as
"send the message 'methname' to 'obj'"
while in Python it's the same as the single step
"get the method named 'methname' from 'obj'"
There isn't a method per se in Ruby, but the base object
class knows how to convert a message into a function
object (a functor) which can then be called. However,
there are no functions in Ruby either, only objects which
take messages. So "f(1)" does not work (well, it can
because "functions" get turned into private methods of
the base object) and instead you call functors with the
"call" message.
Hence, to emulate Python's two-step method invocation
(where you get the bound method in the first step then
call the functor in the second step) in Ruby you need to do
it as
m = obj.method
methname)
m.call(param1, param2)
where 'method' is a method of the base object type which
takes the method name and returns a bound Method object.
(Let me try that again. All objects can receive the message
'method', because it's part of Ruby's base object type. The
'method' message comes with the name of the method. It
returns a new object which, when sent the 'call' message,
forwards that message to the original object but changes the
message type from 'call' to the desired message type, which
in this case was the name 'methname'.
Any better? It really does help if you think of Ruby as sending
message and not as getting callables.)
Of course, the typical Ruby accusation against Python is that it (Ruby) is
"purer OO". I don't know what they mean by "purer".
It is in part because of Python's old class/type dichotomy.
It's also because Python lets you create instances which are
not part of any class or instance. For example, Python has
functions, like
def spam(count):
print "Spam " * count
These are not part of any object. (Well, perhaps the module
object, but it isn't a method of the module type.)
Ruby has syntactic sugar to allow "functions" like this, but under
the covers it ends up making 'spam' be a private method of
the base object class. When you "call" it you really send
the message "spam" with the given count value to the base
object class.
Philosophically then, while you could think of everything in
Python as OO it isn't as "pure" as Ruby because we tend
to think of modules, instances, attributes, variables, and
classes as different things, while Ruby doesn't make that
strong of a distinction between them.
A class is an object, the methods of an instantiated class are
objects, the function a method wraps is an objects, the code of the function
is an object.... I think about the only thing that is not an object in
Python is a name, and I can't think how *that* would work.
Perhaps this is a good way to think of the difference.
Python thinks namespaces are one honking great idea
Ruby thinks OO is one honking great idea
Python's modules, classes, instances, and locals are all
namespaces. They happen to be specific types in a
type system which is nearly unified.
Ruby's modules, classes, instances, and locals are all
instances, each of which defines its own namespace.
(NB: I've never coded Ruby only read the docs and followed
the newsgroup for a couple of months, so my perception
can be wrong, but I suspect it isn't that wrong.)
Andrew
(e-mail address removed)