I'd like to ask, what "container.each" is, exactly? It looks like a
function
call (as I've learned a few posts ago), but, what are its arguments?
How the
looping "works"? Does it receive a "code" object that it has to
execute?
Is .each some kind of magic keyword? (This has little to do with
python or
the current thread, so feel free to reply off-list if you want to...)
#each is simply a method that takes a function (called blocks in
ruby). One could call it a higher-order method I guess.
It's an implementation of the concept of internal iteration: instead
of collections yielding iterator objects, and programmers using those
through specially-built iteration constructs (e.g. `for…in`),
collections control iteration over themselves (the iteration is
performed "inside" the collection, thus the "internal" part) and the
programmer provides the operations to perform at each iterative step
through (usually) a function.
In Python (assuming we had anonymous defs and an each method on
lists), the following loop:
for item in some_list:
do_something(item)
do_something_else(item)
some_list.each((def (item):
do_something(item)
do_something_else(item)
))
There's absolutely nothing magic there, it's simply using anonymous
functions and method calls (SmallTalk initiated this approach in the
70s, and actually went much, much further than Ruby as it did away not
only with `for…in` but also with `if…else` and `while` and a bunch of
other stuff).
Now as IV pointed out, #each isn't the most interesting usage of
blocks/anonymous functions (though I do like it, because it gets rid
of no less than two keywords… even if Ruby reintroduced them as
syntactic sugar), higher-order functions (functions which act on other
functions) are (among other things) ways to create new control
structures without having to extend the core language (so are lisp-
style macros, by the way).
Of course Python does have higher-order functions (functions are first-
class objects, so it's possible and frequent to have functions act on
other functions), but since Python doesn't have anonymous functions
that usage tends to be a bit too verbose beyond simple cases (also, of
course, this kind of usages is neither in the "genes" nor in the
stdlib).
In closing, IV has an example of how blocks make `with` unnecessary in
Ruby (the functionality can be implemented at the library level rather
than the language one). Generally, anonymous functions in OO languages
are a way to inject behavior into third-party methods/objects. Kind-of
a first-class Visitor support.
-m
PS: there's actually a bit of syntactic magic in Ruby's blocks, and
it's one of the things I hate in the language, but it's not relevant
to the role of blocks, and unnecessary to it: SmallTalk has no magical
syntax).