rails - ¿Hay razones técnicas para que una Ruby DSL como RSpec no pueda ser reescrita en Python?
rspec subject (5)
La sección a continuación RSpec más detalles, pero básicamente alguien dijo que la RSpec DSL escrita en RSpec no se podía reescribir en Python. ¿Es eso cierto? Si es así, ¿por qué?
Estoy deseando entender mejor las diferencias técnicas entre Ruby y Python.
Actualización: ¿Por qué estoy haciendo esta pregunta?
La discusión Huyendo de RSpec tiene algunas afirmaciones acerca de que es "imposible" recrear RSpec en Python. Estaba tratando de hacer la pregunta un poco más amplia con la esperanza de aprender más de las diferencias técnicas entre Ruby y Python. En retrospectiva, tal vez debería haber ajustado el alcance de la pregunta para preguntar si realmente es imposible recrear RSpec en Python, y si es así, por qué.
A continuación, se incluyen algunas citas de la discusión Huyendo de RSpec .
Pregunta inicial
Durante las últimas semanas he estado pensando mucho en RSpec y por qué no hay una respuesta clara y definitiva cuando alguien pregunta:
"Estoy buscando un Python equivalente a RSpec. ¿Dónde puedo encontrar algo así?"
Probablemente la respuesta más común (y comprensible) es que la sintaxis de Python no permitiría tal cosa, mientras que en Ruby es posible.
Primera respuesta a la pregunta inicial
No es exactamente la sintaxis. Rspec monkeypatches cada objeto dentro de su alcance, insertando los métodos "should" y "should_not". Puedes hacer algo en Python, pero no puedes hacer un mono de los tipos incorporados.
Otra respuesta
Como sugieres, es imposible. Mote y PySpec son formas sofisticadas de nombrar tus pruebas: implementaciones débiles de un rincón diminuto de RSpec. Mote usa la magia de settrace horrible; PySpec agrega un montón de ruido irrelevante de dominio. Ni siquiera admite cadenas de contexto arbitrarias. RSpec es más terso, más expresivo, elimina el ruido y es algo totalmente razonable de construir en Ruby.
El último punto es importante: no es solo que RSpec es posible en Ruby; En realidad es idiomático.
Al mezclar Mamba y Expects, creo que puedes acercarte mucho a lo que RSpec es para Rails ...
https://github.com/nestorsalceda/mamba
https://github.com/jaimegildesagredo/expects
Además, creo que Specter debe coincidir con sus expectativas con las pruebas:
https://github.com/jmvrbanac/Specter
http://specter.readthedocs.io/en/latest/writing_tests/index.html
Comencé a intentar implementar algo como rspec en Python.
Tengo esto:
with It(''should pass'') as test:
test.should_be_equal(1, 1)
fuente: https://gist.github.com/2029866
(pensamientos?)
EDITAR: Mi respuesta a su pregunta es que la falta de bloques anónimos impide que se reescriba un DSL de Ruby como RSpec en Python, pero puede obtener una aproximación cercana con las declaraciones.
Creo que esto es lo que estás buscando. Sí, hicimos lo "imposible" en python. "sure" es un cinturón de utilidad para las pruebas de python expresivas, creado por Gabriel Falcão.
Uno de los puntos fuertes de Ruby es la creación de DSL. Sin embargo, las razones dadas para que sea difícil en python pueden ser eludidas. Por ejemplo, puede subclasificar fácilmente los tipos incorporados, por ejemplo:
>>> class myint(int): pass
>>> i = myint(5)
>>> i
5
Si fuera a crear un DSL en python, usaría pyparsing o Parsley y algo como lo anterior, optimizando la sintaxis del problema, no el lenguaje de implementación.
Si tuviera que señalar una gran dificultad para crear una RSpec de Python, sería la falta de una buena sintaxis en Python para crear funciones anónimas (como en JavaScript) o bloques (como en Ruby). La única opción para un programador de Python es usar lambdas, que no es una opción en absoluto porque las lambdas solo aceptan una expresión. Los bloques do ... end
utilizados en RSpec deberían escribirse como una función antes de llamar y describe
, como en el siguiente ejemplo:
def should_do_stuff():
# ...
it("should do stuff", should_do_stuff)
No es tan sexy, ¿verdad?
Hay algunas dificultades para crear los métodos should
, pero apuesto a que sería un problema menor. En realidad, uno ni siquiera necesita usar una sintaxis tan inusual, podría obtener resultados similares (quizás incluso mejores, dependiendo de su gusto) usando la sintaxis de Jasmine , que se puede implementar de manera trivial.
Dicho esto, creo que la sintaxis de Python está más centrada en representar de manera eficiente los componentes habituales del programa, como clases, funciones, variables, etc. No está bien adaptada. Por mi parte, creo que un buen programa de Python es uno en el que puedo ver objetos, funciones y variables, y comprendo qué hace cada uno de estos elementos. Los programadores de Ruby, OTOH, parecen buscar un estilo más parecido a la prosa, donde se define un nuevo lenguaje para un nuevo problema. También es una buena forma de hacer las cosas, pero no una forma pitónica. Python es bueno para representar algoritmos, no prosa.
A veces es un límite draconiano. ¿Cómo podría uno usar BDD por ejemplo? Bueno, la forma habitual de ampliar estos límites en Python es escribir efectivamente tu propio DSL, pero REALMENTE debería ser otro idioma. Eso es lo que Pyccuracy es, por ejemplo: otro idioma para BDD. Un ejemplo más general es doctest . (En realidad, si escribiera alguna biblioteca BDD Python, la escribiría en base a doctest.) Otro ejemplo de Python DSL es Twill . Y otro ejemplo más es reStructuredText , usado en Sphinx .
Resumiendo: En mi humilde opinión, la barrera más difícil para los DSL en Python es la falta de una sintaxis flexible para crear funciones anónimas. Y no es un error *: a Python no le gusta que su sintaxis sea muy explorada, se considera que hace que el código sea menos claro en el universo de Python. Si quieres una nueva sintaxis en Python, te recomendamos que escribas tu propio idioma, o al menos así es como me siento.
* O tal vez es - tengo que confesar que me olvido de las funciones anónimas. Sin embargo, reconozco que serían difíciles de implementar con elegancia debido a la muesca semántica de Python.