Подтвердить что ты не робот

Существуют ли технические причины, по которым Ruby DSL, например RSpec, не может быть переписан на Python?

Ниже приведен более подробный раздел, но в основном кто-то заявил, что написанный Ruby DSL RSpec не может быть переписана в Python. Это правда? Если да, то почему?

Я хочу лучше понять технические различия между Ruby и Python.

Обновление: почему я задаю этот вопрос?

В Отключение от RSpec в обсуждении есть некоторые утверждения о том, что это "невозможно" воссоздать RSpec в Python. Я пытался сделать этот вопрос немного шире, надеясь узнать больше о технических различиях между Ruby и Python. Оглядываясь назад, возможно, мне следовало бы ужесточить вопрос, просто спросив, действительно ли невозможно воссоздать RSpec в Python, и если да, почему.

Ниже приведены лишь несколько цитат из обсуждения Отключение от обсуждения RSpec.

Начальный вопрос

В течение последних нескольких недель я много думал о RSpec и почему нет ясного, определенного ответа, когда кто-то спрашивает:

"Я ищу эквивалент Python RSpec. Где я могу найти такой   вещь?"

Вероятно, наиболее распространенным (и понятным) ответом является то, что синтаксис Python не допустил бы такой вещи, тогда как в Ruby это возможно.

Первый ответ на начальный вопрос

Не синтаксис точно. Обезьяна Rspec передает каждый объект внутри своего объем, вставляя методы "should" и "should_not". Ты можешь сделать что-то в python, но вы не можете monkeypatch встроенных типов.

Другой ответ

Как вы полагаете, это невозможно. Mote и PySpec - просто причудливые способы чтобы назвать ваши тесты: слабые реализации одного крошечного угла RSpec. Моте использует ужасную магию; PySpec добавляет кучу шум, несущий домен. Ни один из них не поддерживает произвольный контекст строки. RSpec более тонкий, более выразительный, устраняет шум и это вполне разумная вещь для создания в Ruby.

Эта важная точка важна: это не только то, что RSpec возможно в Рубин; это действительно идиоматично.

4b9b3361

Ответ 1

Если бы я указал на одну большую трудность для создания RSpec Python, это было бы отсутствие хорошего синтаксиса в Python для создания анонимных функций (как в JavaScript) или блоков (как в Ruby). Единственный вариант для программиста Python - использовать lambdas, что не является вариантом вообще, потому что lambdas просто принимают одно выражение. Блоки do ... end, используемые в RSpec, должны быть записаны как функция перед вызовом describe и it, как в примере ниже:

def should_do_stuff():
    # ...
it("should do stuff", should_do_stuff)

Не так сексуально, правда?

Есть некоторые трудности при создании методов should, но я уверен, что это будет меньшая проблема. На самом деле, даже не нужно использовать такой необычный синтаксис - вы можете получить похожие результаты (может быть, даже лучше, в зависимости от вашего вкуса) с помощью Jasmine, который может быть реализован тривиально.

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

Иногда это драконовский предел. Как можно использовать BDD, например? Ну, обычный способ поднять эти ограничения на Python - это эффективно написать собственный DSL, но он должен ДЕЙСТВИТЕЛЬНО быть другим языком. Это то, что Pyccuracy, например: другой язык для BDD. Более важным примером является doctest. (На самом деле, если бы я написал некоторую библиотеку BDD Python, я бы написал ее на основе doctest.) Еще один пример Python DSL - Twill. И еще один пример: reStructuredText, используемый в Sphinx.

Подведение итогов: IMHO самым трудным препятствием для DSL в Python является отсутствие гибкого синтаксиса для создания анонимных функций. И это не ошибка *: Python не любит сильно анализировать свой синтаксис - считается, что код менее понятен в юниверсе Python. Если вам нужен новый синтаксис в Python, вам рекомендуется написать свой собственный язык или, по крайней мере, так, как я себя чувствую.

* Или, может быть, это - я должен признать, что я пропускаю анонимные функции. Тем не менее, я понимаю, что их было бы сложно реализовать элегантно, учитывая семантический отступ Python.

Ответ 2

Одна из сильных сторон Ruby заключается в создании DSL. Однако причины, по которым это трудно в питоне, можно обойти стороной. Например, вы можете легко подклассифицировать встроенные типы, например:

>>> class myint(int):  pass
>>> i = myint(5)
>>> i
5

Если бы я собирался создать DSL в python, я бы использовал pyparsing или Parsley и что-то вроде выше за кулисами, оптимизируя синтаксис проблемы, а не язык реализации.

Ответ 3

Я попытался реализовать что-то вроде rspec в Python.

Я получил это:

with It('should pass') as test:
    test.should_be_equal(1, 1)

источник: https://gist.github.com/2029866

(мысли?)

EDIT: Мой ответ на ваш вопрос заключается в том, что отсутствие анонимных блоков не позволяет Ruby DSL, как RSpec, переписываться в Python, но вы можете получить близкое приближение с помощью операторов.

Ответ 5

Я думаю, что это то, что вы ищете. Да, мы сделали "невозможным" в python "sure" является поясником для экспресс-тестов на python, созданный Габриэлем Фалькао