RubyLanguage and PythonLanguage often take ideas from each other. * RubyLanguage's *rest argument syntax came from PythonLanguage. Python has had KeywordParameterPassing since the beginning; Ruby will it them in 2.0. Ruby: def foo(a, b=default, *rest) ... end Python: def foo(a, *rest, b=default): ... * Python unified long integers and small integers in version 2.4. Ruby already had Fixnum/BigNum integration. * Python 2.4 adds a Decimal library which allows arbitrary precision decimal math. Ruby had a BigDecimal one for a while. * RubyLanguage had iterators and ''yield'' since the beginning; PythonLanguage added them later. But Python's CoRoutine-ish generators have some advantages over InternalIterator''''''s, so now Ruby has the Generator class (built with CallWithCurrentContinuation in 1.8 or Threads in 1.9 and InternalIterator''''''s). [Compare GeneratorsAreNotCoroutines.] Python's generators allow you to mix calls to more than one generator at a time and in Python 2.5 more coroutine features have been added to allow the caller to send values to a generator, raise an exception in the generator, or terminate it. 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) * Class variables in RubyLanguage were shared in a class hierarchy, while in PythonLanguage they were class-specific; now Ruby follows this rule too. * Ruby 1.8 introduced the colon as possible syntax in the for statement for in [: | then] : which is identical to the pythonic for in : * Even if PythonPhilosophy says, "Sparse is better then dense" PythonLanguage is approaching density. For example, some methods like sort() used to return None and you could not write stuff like the Rubyish open('sorted.txt','w').puts open('in.txt').sort : But now classes like sorted allow you to write in PythonLanguage: PrivoxyWindowO''''''pen('sorted.txt','w').writelines(sorted(PrivoxyWindowO''''''pen('in.txt'))) * When PythonLanguage introduced the __iter__ protocol, it gained 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) end Or: File.foreach("foo.txt") { |f| do_stuff(f) } * The PythonLanguage interpreter in 2.4 got a '-m' option to load modules from the cli, useful for one-liners and such. RubyLanguage had this ('-r') since the beginning (part of its PerlLanguage inheritance). * Python's context managers (syntax: "with" clause) enable error handing patterns similar to how blocks are sometimes used in Ruby (http://www.python.org/dev/peps/pep-0343/) ---- 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 LexicalClosure''''''s/AnonymousMethod''''''s 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 Index''''''Error if i != self.counter: raise Assertion''''''Error("forward iteration only") x = self.callable() if x == self.sentinel: self.at_end = 1 raise Index''''''Error 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. ! ---- CategoryPython CategoryRuby CategoryComparisons