Что есть у Ruby, чего нет у Python, и наоборот?

Существует много дискуссий о Python против Ruby, и я все нахожу их совершенно бесполезными, потому что все они оборачиваются тем, почему функция X отстой в языке Y или что утверждают, что язык Y не имеет X, хотя на самом деле это так. Я также точно знаю, почему я предпочитаю Python, но это также субъективно и не поможет никому выбрать, поскольку у них могут не быть те же вкусы в разработке, что и у меня.

Поэтому было бы интересно перечислить различия объективно. Так что никакие "лямбды Python" - отстой ". Вместо этого объясните, что может делать лямбда-труба Ruby, что не может Python. Нет субъективности. Пример кода это хорошо!

Не имейте несколько различий в одном ответе, пожалуйста. И проголосуйте за тех, кого вы знаете, правильно, и за тех, кого вы знаете, неправильно (или субъективно). Также различия в синтаксисе не интересны. Мы знаем, что Python делает с отступом то, что Ruby делает с помощью скобок и концов, и что в Python @ называется self.

ОБНОВЛЕНИЕ: Теперь это вики сообщества, поэтому мы можем добавить большие различия здесь.

Ruby has a class reference in the class body

В Ruby у вас есть ссылка на класс (self) уже в теле класса. В Python у вас нет ссылки на класс до тех пор, пока не будет завершено построение класса.

Пример:

class Kaka
  puts self
end

В этом случае self - это класс, и этот код выведет «Kaka». Невозможно распечатать имя класса или каким-либо другим способом получить доступ к классу из тела определения класса в Python (вне определения метода).

All classes are mutable in Ruby

Это позволяет вам разрабатывать расширения для основных классов. Вот пример расширения рельсов:

class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

Python (представьте, что не было''.startswith метод):

def starts_with(s, prefix):
    return s[:len(prefix)] == prefix

Вы можете использовать его в любой последовательности (не только в строках). Для того, чтобы использовать его, вы должны импортировать егоexplicitly например.,from some_module import starts_with.

Ruby has Perl-like scripting features

В Ruby есть регулярные выражения первого класса, переменные $, переменный цикл построчного ввода awk / perl и другие функции, которые делают его более подходящим для написания небольших сценариев оболочки, которые разбирают текстовые файлы или действуют как связующий код для других программ.

Ruby has first class continuations

Благодаря заявлению callcc. В Python вы можете создавать продолжения различными способами, но в язык не встроена поддержка.

Ruby has blocks

С помощью "do" С помощью оператора вы можете создать многострочную анонимную функцию в Ruby, которая будет передана в качестве аргумента в метод перед do и будет вызываться оттуда. В Python вы бы вместо этого делали это либо передавая метод, либо с помощью генераторов.

Рубин:

amethod { |here|
    many=lines+of+code
    goes(here)
}

Python (блоки Ruby соответствуют различным конструкциям в Python):

with amethod() as here: # `amethod() is a context manager
    many=lines+of+code
    goes(here)

Или же

for here in amethod(): # `amethod()` is an iterable
    many=lines+of+code
    goes(here)

Или же

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

Интересно, что в Ruby оператор удобства для вызова блока называется «yield», который в Python создаст генератор.

Рубин:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

def themethod():
    yield 5

for foo in themethod():
    print foo

Хотя принципы разные, результат поразительно похож.

Ruby supports functional style (pipe-like) programming more easily
myList.map(&:description).reject(&:empty?).join("\n")

Python:

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Python has built-in generators (which are used like Ruby blocks, as noted above)

В Python есть поддержка генераторов на языке. В Ruby 1.8 вы можете использовать модуль генератора, который использует продолжения для создания генератора из блока. Или вы можете просто использовать блок / proc / lambda! Более того, в Ruby 1.9 Fibres являются и могут использоваться как генераторы, а класс Enumerator является встроенным генератором.4

docs.python.org имеет этот пример генератора:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

Сравните это с приведенными выше примерами блоков.

Python has flexible name space handling

В Ruby, когда вы импортируете файл сrequireвсе вещи, определенные в этом файле, окажутся в вашем глобальном пространстве имен. Это вызывает загрязнение пространства имен. Решением для этого являются модули Rubys. Но если вы создаете пространство имен с модулем, то вы должны использовать это пространство имен для доступа к содержащимся классам.

В Python файл является модулем, и вы можете импортировать содержащиеся в нем имена с помощьюfrom themodule import *тем самым загрязняя пространство имен, если хотите. Но вы также можете импортировать только выбранные имена сfrom themodule import aname, another или вы можете простоimport themodule а затем получить доступ к именам сthemodule.aname, Если вам нужно больше уровней в вашем пространстве имен, вы можете иметь пакеты, которые являются каталогами с модулями и__init__.py файл.

Python has docstrings

Строки документации - это строки, которые присоединяются к модулям, функциям и методам и могут быть самоанализ во время выполнения. Это помогает создавать такие вещи, как команда справки и автоматическая документация.

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

Эквивалент Ruby аналогичен javadoc и расположен над методом, а не внутри него. Они могут быть извлечены во время выполнения из файлов, используя метод 1.9 # source_locationпример использования

Python has multiple inheritance

Ruby не («специально» - см. Веб-сайт Ruby,посмотрите, как это делается в Ruby). Он повторно использует концепцию модуля как тип абстрактных классов.

Python has list/dict comprehensions

Python:

res = [x*x for x in range(1, 10)]

Рубин:

res = (0..9).map { |x| x * x }

Python:

>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Рубин:

p = proc { |x| x * x }
(0..9).map(&p)

питон2.7+:

>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}

Рубин:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Python has decorators

Вещи, подобные декораторам, также могут быть созданы в Ruby, и также можно утверждать, что они не так необходимы, как в Python.

Syntax differences

Ruby требует & quot; конец & quot; или & quot;} & quot; закрыть все свои области, в то время как Python использует только пробелы. В Ruby недавно предпринимались попытки разрешить использование только пробеловhttp://github.com/michaeledgar/seamless