"Andrew Dalke" <adalke at mindspring.com> wrote in message
news:bhrmk0$hi7$1 at slb0.atl.mindspring.net...
All of the Ruby collections implement a .each method, which is
a version of the Visitor pattern. If I want to do something to every element
in a list or a dict (or any kind of collection,) all I have to do is say
something like (using Python syntax):
Does that mean 'apply the method to each element of my
collection?'? Does it return a new container or modify things
in-place? Is it applied recursively?
I think that's something that each object which implements .each
needs to specify.
have to worry about distinctions between functions and methods. In other
words, it's a mess compared to Ruby.
Where does that distinction come into play? A method is a bound
function, kinda like a curried function with self.
Ruby doesn't have functions in the sense that Python does. Since
a module is treated as a class without instances, module level
functions are class methods: they have the module itself as the instance.
I find this to be a conceptually cleaner way of handling the
I find C++ methods more confusing, because a reference to a
class method is unbound, when I almost always want it bound.
Well, in C++, there is no class object to bind it to. I think that's
a difficulty in C++, but then, I don't use the language.
Now, you can say: "We've got that with map()." Well, we've got it when
your inputs are either lists (or implement the correct protocol) but the
result is a list, it's not an internal modification to the object's
Ahh. Are strings in Ruby mutable or immutable? ... Yup,
looks like it's mutable. From the FAQ
a = "HELLO"
puts a #=> "hello"
In which case it makes more sense for this in Ruby than in
can't do that much unless f modifies state, either as a bound
method or tweaking global variable.
Given that rather fundamental difference, an each method
in Python + code blocks wouldn't be any more powerful
than a for statement. The following is possible
def each(container, f):
for i, x in enumerate(container):
container[i] = f(container[i])
but then it requires the container be indexable, which
is stronger than just being iterable.
The major difference is in program expressiveness.
As I said, a For statement is a statement, while .each
is an expression, even when followed by a code block.
There's a considerable difference in the way the program
is laid out, which makes a difference in how easy it is to
determine what is being done.
How do Ruby's associative arrays work when the string used
as the key is mutated in-place? Is it copy-on-write?
I believe that's true for strings: they're used enough that there's
a special provision for them. For other objects, it's up to the
object type to maintain its hash value properly, or to the
application to rehash the dictionary.
I don't really consider this to be the best policy, though.
I like the Python solution better, though: solve the problem
by not allowing mutable values as keys.
To continue on this vein, Ruby directly implements Visitor, Observer,
Delegate and Singleton. I don't particularly like the way it does some
of them, but Python can't claim any one of the four!
The Python approach to a Singleton is called a 'Borg' class.
I knew I should have said: "And don't tell me about Borg.
It's a bloody hack that never should have been invented,
and should be quietly buried at the crossroads with a stake
through its heart now that it's possible to do it properly."
And I have said it before, on this newsgroup, in fact.
The other way to get singletons is with a factory function,
which under Python wouldn't look different than a normal
constructor. I looked at some Java code recently and
wanted to suggest a factory implementation only to realized
that would require a lot of 'new' removals.
Well, yes. You've always been able to do that, and
the Ruby mechanism is basically a class function. The
thing that the __new__() method (and Borg, to give it
its due) does that neither the factory function nor the
alternate constructor does is use the proper convention
for creating the instance: that is, the class's name.
That means that if you want to convert it from a singleton,
you've got a greater chance of having code you don't have
Despite my best attempts, I find it almost impossible to slag someone
without including information to back up my view. Eg, I thought my
numbers and trends of mentions of other programming languages was
pretty interesting, but I guess it was of no value to you. :(
I found it interesting, but not to the point. If there is one,
it's simply a question of whether any of the differences are
significant enough so someone who knows one language would
consider switching to another one. Google searches won't tell
you that, only looking for people who've made that switch
will tell you.
And I doubt if you'll find them on this newsgroup. That's the
one problem I have with Brandon's questions. If I wanted
to find out whether someone considered Ruby to be sufficiently
better than Python to switch, I'd look on the Ruby newsgroup,
not this one.
I'm basically taking it from the viewpoint of whether there's
anything in Ruby that I think would be good in Python, which
is a question that might interest people on this NG.
dalke at dalkescientific.com