RubyLanguage and PythonLanguage often take ideas from each other.
def foo(a, b=default, *rest) ... endPython:
def foo(a, *rest, b=default): ...
Ruby's internal iterators may be chained through several calls: array.find { |x| x.even? }.map { |x| x + 2 }.sort_by { |x| x % 5 }
Python uses "generator expressions" to perform iterative inline operations: sorted((x+2 for x in array if x%2 == 0), key=lambda x: x%5)
for <vars> in <object> [: | then]
for <vars> in <object>:
open('sorted.txt','w').puts open('in.txt').sort
PrivoxyWindowOpen('sorted.txt','w').writelines(sorted(PrivoxyWindowOpen('in.txt')))
for line in open('foo.txt'): do_stuff(line)which RubyLanguage supported since the beginning.
This could also be written in Ruby as:
File.open('foo.txt').each do | line | do_stuff(line) endOr:
File.foreach("foo.txt") { |f| do_stuff(f) }
While they may be converging superficially, Ruby and Python's library and user community are moving in very different directions.
Rails is a great example of the RubyWay, which is utterly dynamic in both typing and behavior. Python and Ruby are languages competing for a similar bracket, so they will always appear to be "converging," because smart people are finding the key features. But the philosophy of each language, and the way the community uses them, are utterly different.
Python is moving in a direction where the "ideals" are captured by the decisions made in by GVR. The PythonLanguage additions and modifications are often taken from other languages but are carefully rethought and reworked through discusion and research to represent the concensus of "The best/clearest way to solve this problem". This allows many programmers to share code that "feels" similar, despite having different authors.
[[ Substitute Python -> Ruby and GVR -> Matz in the above, and the statement would still hold, IMHO ]]
A lot of the features have really converged in the new BooLanguage. Boo has a Python syntax but supports LexicalClosures/AnonymousMethods and optional explicit StaticTyping declarations.
This is a bunch of hooey.
The unification of int and long started with 2.0.
Java has BigDecimal; is it also converging? All languages support strings - they must be the same language!
Python's __iter__ protocol is not the same as Ruby's code block approach. For example, in Ruby I can make new control flow through code blocks, while in Python I cannot make new syntax.
The "with" statement in PEP 343 has *nothing* to do with code blocks. It's new syntax for a very limited scenerio (resource management) where code blocks easily provide a more general implementation space.
Well before the __iter__ protocol you could do
for line in open('foo.txt'): do_stuff(line)with a wrapper which implemented __getitem__ correctly, as
class Iter: def __init__(self, callable, sentinel=None): self.callable = callable self.sentinel = sentinel self.at_end = 0 self.counter = 0 def __getitem__(self, i): if self.at_end: raise IndexError if i != self.counter: raise AssertionError("forward iteration only") x = self.callable() if x == self.sentinel: self.at_end = 1 raise IndexError self.counter = self.counter + 1 return x for line in Iter(open('foo.txt').readline, ""): do_stuff(line)I think this works even back to Python 1.0. The advantage is the iter protocol doesn't overload __getitem__, which has the expectation of being random access. That is, open("foo.txt")[5] shouldn't look like it would work and return the 6th line of the file. !